if (!Regio._Modules)
    Regio._Modules = {};
/**
 * Component: Regio.Route.VisitestoniaProvider
 * Provider for Regio.Route
 *
 * Requires: Regio.Route, jQuery
 *
 * Group: Route
 *
 * Version: 1.000000
 *
 * Author:
 * Alexandr Smirnov (alex@regio.ee)
 * Riivo Kikas
 */
Regio.Route.CreateVisitestoniaProvider = function(cfg){
    cfg = cfg ||
    {};

    Regio.Utils.applyDefaults(cfg, {
        bridgePath: '',
        idPrefix: ''
    });

    var provider = {
        abort: function(){
            if (this.lastAjax) {
                this.lastAjax.abort();
                this.lastAjax = null;
            }
        },
        getRoute: function(route, mapapi, queryDescription, querySegments, bbox, generalization, onCompleteCallback){
            var me = this;
            var points = route.getPoints(), pointsArr = [];
            // convert way points to routing request format (x,y;x,y)
            for (var i = 0; i < points.length; i++) {
                var en = points[i];
                if (cfg.inputCoordsConvertProc) {
                    en = cfg.inputCoordsConvertProc(points[i]);
                }
                pointsArr.push([en.e, en.n].join(','));
            }

            // do request
            var opts = {
                dataType: 'xml',
                error: function(e, t){
                    // onCompleteCallback accept params: isError, errorDescription
                    onCompleteCallback(true, t);
                },
                success: function(data){
                    if (queryDescription) {
                        me.lastServerParams = $('route server', data).attr('params');

                        var desc = $('route desc', data);
                        var legs = $('route leg', data), arr = [];
                        // make legs to objects
                        for (var i = 0; i < legs.length; i++) {
                            arr.push({
                                id: cfg.idPrefix + $(legs[i]).attr('id'),
                                turn: ('' + $(legs[i]).attr('turn')).toLowerCase(),
                                text: decodeURIComponent($(legs[i]).attr('text'))
                            })
                        }
                        // we have all we need for setting description
                        // setDescription first parameter is array of arrays (one array for every way point),
                        // but that is not required (could be any data in format of Regio.TreeView2)
                        route.setDescription([arr, []], {
                            length: desc.attr('length'),
                            time: desc.attr('time')
                        });
                    }

                    if (querySegments) {
                        var wayPointNum = 0;
                        var objs = $('route obj', data);

                        objs.each(function(){
                            var id = cfg.idPrefix + $(this).attr('id');

                            var arr = [];
                            $('crd', this).each(function(){
                                var p = {
                                    e: parseFloat($(this).attr('E')),
                                    n: parseFloat($(this).attr('N'))
                                };
                                if (cfg.outputCoordsConvertProc) {
                                    p = cfg.outputCoordsConvertProc(p);
                                }
                                arr.push(p);
                            });

                            route.updateSegment(wayPointNum, id, {
                                text: $(route.getDescription()[wayPointNum]).filter(function(){
                                    return this.id == id
                                })[0].text,
                                points: arr
                            })
                        });
                    }

                    if (queryDescription) {
                        // do update request right away
                        me.getRoute(route, mapapi, false, querySegments, bbox, generalization, onCompleteCallback);
                        onCompleteCallback();
                    }
                    else {
                        onCompleteCallback();
                    }
                }
            };

            if (queryDescription) {
                // url params
                opts.url = cfg.bridgePath, opts.type = 'GET';
                opts.data = {
                    request: 'description',
                    points: pointsArr.join(';'),
                    locale: 'est',
                    srs: 'EPSG:3301'
                };
            }
            else
                if (querySegments) {
                    /*if (!Regio.Utils.isArray(bbox) || (bbox.length != 4)) {
                 throw new Error('RouteDelfiProvider, passed bbox for update must be array with length = 4');
                 }*/
                    if (!bbox)
                        bbox = [0, 0, 99999999, 99999999];
                    if (!generalization)
                        generalization = 100;
                    // url params
                    var b1 = {
                        e: bbox[0],
                        n: bbox[1]
                    };
                    var b2 = {
                        e: bbox[2],
                        n: bbox[3]
                    };
                    if (cfg.inputCoordsConvertProc) {
                        b1 = cfg.inputCoordsConvertProc(b1);
                        b2 = cfg.inputCoordsConvertProc(b2);
                    }

                    opts.type = 'POST';
                    var payload = this.lastServerParams ? '<?xml version="1.0"?><data><params>' + decodeURIComponent(this.lastServerParams) + '</params></data>' : '';
                    //opts.data = {"data": payload };
                    opts.url = Regio.Utils.format(cfg.bridgePath + '?request=update&points={points}&locale=est&srs=EPSG:3301&gen={gen}&e1={e1}&n1={n1}&e2={e2}&n2={n2}&data={data}', {
                        points: pointsArr.join(';'),
                        gen: generalization,
                        e1: b1.e,
                        n1: b1.n,
                        e2: b2.e,
                        n2: b2.n,
                        data: payload
                    });
                    opts.contentType = "text/xml";
                }

            if (!queryDescription && !this.lastServerParams) {

                // if its update request and there are no lastServerParams then it means that
                // description request have not completed... we can do nothing here, just ignore it
                // (probably should put it into some queue in future)
            }
            else {
                this.abort();
                this.lastAjax = jQuery.ajax(opts);
            }
        }
    }

    return provider;
}
Regio.SearchList.VisitEstoniaObjectProvider = function(cfg){
    cfg = cfg ||
    {};
    var lastAjax;
    return function(query, listeners, onSuccess, onError){

        var opts = {
            type: 'GET',
            dataType: 'json',
            url: Regio.Utils.format(cfg.uri, jQuery.extend({
                query: encodeURIComponent(query)
            }, cfg.params)),
            error: function(req, desc){
                onError(desc);
            },
            success: function(json){
                var arr = json;
                $(arr).each(function(){
                    this.vistesoniaobject = "visitesoniaobject";
                });
                onSuccess(arr);
            }
        };

        opts = jQuery.extend(opts, cfg);
        listeners.broadcast("submit", opts);

        if (lastAjax)
            lastAjax.abort();
        lastAjax = jQuery.ajax(opts);
    }
}


Regio._Modules['tours'] = function(){
    LoadPage('[wrapperForTemplate=tours]', "templates/tours.html", ".templateBody", function(){
		var tree = Regio.TreeView2('tours-tree', {
			treeTemplate: Regio.Utils.initTemplate('tours-tree', 'html'),
			branchFirstItemIsHeaderDescriptor: true,
			treeStartsWithHeader: false
		});

		tree.beforeDrawHeader = function(arr, childs, firstBranch) {
			$(".expander, .collapser", childs[0])
			.bind("click", function() {
				var $childs = $('.childs', $(this).closest('.layer_group'));

				$childs.slideToggle(300, function() {
					var $childs = $('.childs', $(this).closest('.layer_group'));

					if($childs.css('display') == 'none') {
						$('.expander, .collapser', $(this).closest('.layer_group').addClass('expander').removeClass('collapser')).addClass('expander').removeClass('collapser');
					} else {
						$('.expander, .collapser', $(this).closest('.layer_group').addClass('collapser').removeClass('expander')).addClass('collapser').removeClass('expander');
					}
				});

				return false;
			})
			.each(function() {
				var $childs = $('.childs', $(this).closest('.layer_group'));

				$(this.nextSibling).css('display', 'block'); // safari fix

				if(($childs.css('display') == 'none') || $childs.is(':animated')) {
					$(this).closest('.layer_group').addClass('expander').removeClass('collapser')
					$(this).addClass('expander').removeClass('collapser');
				} else {
					$(this).closest('.layer_group').addClass('collapser').removeClass('expander')
					$(this).addClass('collapser').removeClass('expander');
				}
			});
		}

		tree.beforeDrawNode = function(arr, childs) {
			var $childs = $(childs);
			$(":checkbox", childs).click(function() {
				if($(this).is(':checked')) {
					$(this).data('route', Routes.add(arr.route, false, $childs));
				} else {
					$(this).data('route').shutdown();
					$(this).removeData('route');
				}
				Regio._State('tours', $('[tour]:checked').map(function() { return $(this).attr('tour') }).get());
			});
		}

		tree.afterDrawNode = function(arr, childs) {
			var tours = Regio._State('tours') ? Regio._State('tours').split(',') : [];

			if($.inArray(''+arr.id, tours) != -1) {
				var $c = $(":checkbox", childs).attr('checked', 'true');
				$c.data('route', Routes.add(arr.route, true, childs));
			}

			$(childs).hover(function() {
				$(this).addClass('highlight');
			}, function() {
				$(this).removeClass('highlight');
			});
		}

        //load data
        $.getJSON(env.PARAM_regio.tourList, function(routeData){
            tree.setData(routeData);
        });

		Regio._Tours = {
			clear: function() {
				$('#tours-tree :checkbox:checked').removeAttr('checked').each(function() {
					$(this).data('route').shutdown();
					$(this).removeData('route');
				});
				Regio._State('tours', $('[tour]:checked').map(function() { return $(this).attr('tour') }).get());
			}
		}
	});
}




// search controller
// requires Map
Regio._Modules['search'] = function(){
    // hide the whole thing while intiing
    var $div = $('[wrapperForTemplate=search]').css("visibility", "hidden");
    var mapParams = false; // will be filled with mapParams
    var mapLayer = new Regio.FeaturesRenderer.FT(Regio._Map).createLayer();

    LoadPage($div, "templates/search.html", ".templateBody", function(){
        Regio._LoadModule('routing', function(){

            function fixHeights(){
                fixHeight('.searchList');
                fixHeight('.routing_content');
            }
            function fixHeight(element){
                var $div = $(element);
                var childsHeight = 0;
                $('>*:visible', $div.parent()).each(function(){
                    childsHeight += $(this).outerHeight()
                });
                var resultHeight = $div.parent().outerHeight() - childsHeight + $div.outerHeight();

                $div.css("height", resultHeight);
            }

            var parent = $(".accordion");
/*            var resultHeight = parent.outerHeight();
            if (resultHeight == 0) {
                resultHeight = 549;
            }
            $('.header', parent).each(function(){
                resultHeight -= $(this).outerHeight();
            });
*/
			var searchHeader = $('.search_header', parent);
            var routeHeader = $('.routing_header', parent);


            $('.routing_content').bind("routing:started", function(){
                if (!$('.accordion .ui-accordion-content-active:has(.routing):visible').length) {
                    if (!routeHeader.hasClass("ui-accordion-header-active"))
                        routeHeader.click();
                }
            });

/*
            var toggleActive = function(elem){
                elem.toggleClass("ui-accordion-header-active").toggleClass("ui-state-active").toggleClass("ui-state-default").toggleClass("ui-corner-bottom").find("> .ui-icon").toggleClass("ui-icon-triangle-1-e").toggleClass("ui-icon-triangle-1-s").end().next().toggleClass("ui-accordion-content-active").toggle();

            };

            $('.accordion').addClass("ui-accordion ui-widget ui-helper-reset").find(".header").addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-top ui-corner-bottom").prepend('<span class="ui-icon ui-icon-triangle-1-e"/>').click(function(){
                var element = $(this).next();
                if (!element.hasClass("partiallyOpen")) {
                    toggleActive($(this));
                }
                else {
                    $('.accordion_body', parent).removeClass("partiallyOpen");
                }

                if ($(this).hasClass("search_header")) {
                    if (routeHeader.hasClass("ui-accordion-header-active"))
                        toggleActive(routeHeader);

                }
                else
                    if ($(this).hasClass("routing_header")) {
                        if (searchHeader.hasClass("ui-accordion-header-active"))
                            toggleActive(searchHeader);
                    }

                if (element.hasClass("ui-accordion-content-active"))
                    element.css("height", resultHeight);
                fixHeights();
                return false;

            }).next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").hide();
*/
/*
            $('.accordion_body', parent).each(function(){
                toggleActive($(this).prev());
                $(this).show().addClass("partiallyOpen").css("height", (resultHeight / 2));

            });
*/
            var activeTab = 0;
			var animation = jQuery.browser.msie ? false : 'swing';
			$('.accordion').accordion({
				header: '.header',
				fillSpace: true,
//				autoHeight: true,
				animated: animation,
				collapsible: true,
				active: activeTab,
				change: function(event, ui){
//						fixHeights();
						activeTab = ui.newHeader;
					}
			});
//            fixHeights();



            var formChecker = function(e){
                var filled = $('[name=q]', $div).val();
                $('.search_message_empty_search', $div)[filled ? "hide" : "show"]();
                e.cancel = !filled;
            };

            $('.search_form', $div).submit(formChecker);
            $('.search_submit', $div).click(formChecker);


            var autocomplete = Regio.SearchList.createAutocompleteProvider(env.PARAM_regio.user, {
                uri: env.PARAM_regio.autocomplete_uri
            });


            autocomplete.beforeFormatURL = function(obj){
                var $radios = $('.search_radio input:radio');
                var val = $radios.filter(':checked').attr('ref');
                if (val.indexOf("object") != -1) {
                    obj.uri = env.PARAM_regio.objectAutocompleteURL;
                }
            }

            var search = Regio._Search = Regio.SearchList.createFromMarkup($('.search_list', $div), {
                rowsPerPage: 10,
                providers: {
                    address: Regio.SearchList.createProviderRegioJGCJSONP(env.PARAM_regio.user, {
                        uri: env.PARAM_regio.searchProviderURL,
                        maxCount: 50
                    }),
                    object: Regio.SearchList.VisitEstoniaObjectProvider({
                        uri: env.PARAM_regio.objectSearchProviderURL
                    })
                },
                animation: true,
                autocomplete: autocomplete,
                tabFilter: function(tab, obj){
                    if (tab == 1) {
                        return mapParams && (obj.e >= mapParams.min_e) && (obj.n >= mapParams.min_n) && (obj.e <= mapParams.max_e) && (obj.n <= mapParams.max_n);
                    }
                }
            });

            function centerToSearchResult(r){
                if (r.vistesoniaobject) {
                    var coordsE = r.e.split(",");
                    var coordsN = r.n.split(",");
                    var ids = r.id.split(",");
                    Regio._Map.broadcastOnReady("layers.addSystemLayer", mapLayer.id);
                    for (c = 0; c < coordsE.length; c++) {
                        if (coordsE[c].length < 1 && coordsN[c].length < 1)
                            continue;

                        var id = coordsE.length > 1 ? parseInt(r.serial) * 10 + c : parseInt(r.serial) + c;
                        Regio._Map.broadcastOnReady("layers.addPointToSystemLayer", mapLayer.id, {
                            objectId: id,
                            geo: [{
                                e: coordsE[c],
                                n: coordsN[c]
                            }],
                            color: '00FF00',
                            symbolId: (id > 9) ? 'label2_' + id : 'label1_' + id,
                            alpha: '100',
                            tooltip: r.address,
                            info: ids[c]
                        });
                    }
                    Regio._addOnClick(r);
                    Regio._State('objects', r.address);
                    Regio._Map.broadcastOnReady("layers.centerToSystemLayer", mapLayer.id);

                }
                else {
                    Regio._Map.broadcastOnReady('mapcat.makeSearchResult', {
                        e: r.e,
                        n: r.n,
                        z: r.z,
                        shortName: r.address
                    });
                }
            }

            search.listeners.add("message", function(type){
                if (type == "clear") {
                    mapLayer.clear();
                    Regio._Map.broadcastOnReady('mapcat.removeSearchResult');
                }
            });

            search.listeners.add("items", function(results){
                mapLayer.clear();
                if (results.length) {
                    // center to first result
                    centerToSearchResult(results[0]);
                }
            });


            search.listeners.add("row", function(r, c, i, j, t){

                $(c).attr('serial', r.serial).hover(function(){
                    // object id is actually its serial number
                    Regio._Map.broadcastOnReady("objects.callOnRollOver", mapLayer.id, r.serial);
                    $(this).addClass('highlighted');
                }, function(){
                    Regio._Map.broadcastOnReady("objects.callOnRollOut", mapLayer.id, r.serial);
                    $(this).removeClass('highlighted');
                });
                r.lat = r.e;
                r.lon = r.n;
                // set routing buttons
                $('.route_set_start', c).click(function(){
                    if ((typeof r.e == "string" && r.e.indexOf(",") != -1) || (typeof r.n == "string" && r.n.indexOf(",") != -1))
                        return false;
                    Regio._Map.broadcastOnReady("routing.startPointFixed", {
                        e: r.e,
                        n: r.n,
                        locationName: r.address,
                        center: true
                    }, true);
                    return false;
                });
                $('.route_set_end', c).click(function(){
                    if ((typeof r.e == "string" && r.e.indexOf(",") != -1) || (typeof r.n == "string" && r.n.indexOf(",") != -1))
                        return false;
                    Regio._Map.broadcastOnReady("routing.endPointFixed", {
                        e: r.e,
                        n: r.n,
                        locationName: r.address,
                        center: true
                    }, true);
                    return false;
                });

            });

            search.listeners.add("rowClick", function(r){
                centerToSearchResult(r);
            });

            // setup mutual highlight (see also "row" event)
            Regio._Map.listeners.add("objects.onMouseOver", function(desc){
                // desc.objectId == serial
                $('[serial=' + desc.objectId + ']', $div).addClass('highlighted');
            }).add("objects.onMouseOut", function(desc){
                $('[serial=' + desc.objectId + ']', $div).removeClass('highlighted');
            });

            // make second tab filtering work
            var onMapParams = function(p){
                mapParams = p;
                search.refresh(1);
            }
            onMapParams(Regio._Map.call("map.getMapParameters"));
            Regio._Map.listeners.add("map.onMapParams", onMapParams);

            $(".clear_search_points", $div).click(function(){
                mapLayer.clear();
                Regio._Map.broadcastOnReady('mapcat.removeSearchResult');
                search.clear();
                Regio._Map.broadcastOnReady("layers.clearSystemLayer", mapLayer.id);
                return false;
            }).attr('href', '#');
            if (Regio._State('objects')) {
                var name = Regio._State('objects');
                var parent = $('.search_list', $div);
                $('.search_form input[name=q]', parent).val(name);
                $('[providerName=object]', parent).attr('checked', 'checked');

                var q = $('.search_form input[name=q]', parent).val();
                var pn = $('[providerName=object]:checked', parent).attr('providerName');
                search.submit(q, pn);

            }

            $div.css("visibility", "");
        }); // LoadModule
    }); // LoadPage
}

// routing controller

Regio._Modules['routing'] = function(){
    var uid = env.PARAM_regio.user;
    var cfg = {};
    var ft = Regio._Map;

    if (cfg && cfg.noDescription) {
        $('.routing_content').hide();
    }
    var renderer = Regio.Route.CreateFlashTileRenderer(ft, cfg);
    var provider = Regio.Route.CreateVisitestoniaProvider({
        inputCoordsConvertProc: function(p){
            if (p.e <= 360.0 && p.n <= 360.0 && p.e != 0 && p.n != 0) {
                var p = Regio.Coords.Convert(p.e, p.n, "EPSG:4326", "EPSG:3301");
                return p;
            }
            return p;

        },
        outputCoordsConvertProc: function(p){
            if (p.e > 1000 && p.n > 1000 && p.e != 0 && p.n != 0) {
                var p = Regio.Coords.Convert(p.e, p.n, "EPSG:3301", "EPSG:4326");
                return p;
            }
            return p;

        },
        bridgePath: env.PARAM_regio.routeBridge
    });

    var route = Regio._Routing = new Regio.Route($('.routing_content')[0], ft.listeners, {
        providers: {
            delfiRouting: provider
        },
        renderers: [renderer]
    });

    var oddRow = false;

    ft.addCallback("map.onMapParams", function(args){

        if (args) {
			with (args) {
				var width = max_e - min_e, height = max_n - min_n;
				route.updateForBBox([min_e - width / 2, min_n - height / 2, max_e + width / 2, max_n + height / 2], 100);
			}
		}

    });

    route.listeners.add("requestStarted", function(type){
        $('.route_message').hide();
        $('.route_message_wait').show();
    }).add("requestError", function(desc){
        $('.route_message').hide();
        $('.route_message_error').show();
    }).add("requestComplete", function(desc){
        $('.route_message').hide();
    }).add("clearDescription", function(){
        oddRow = true;
        $('.only_visible_when_route').hide();
    }).add("drawDescription", function(data, overview){
        $('.route_length').text(overview.length);
        $('.route_time').text(overview.time);
        $('.only_visible_when_route').show();
    }).add("row", function(obj, pos, childs){
        var objectID = obj.id, wayPointNum = pos[0];
        $('A', childs).bind("mouseover", function(){
            renderer.listeners.broadcast("hiliteSegment", wayPointNum, objectID);
        }).bind("mouseout", function(){
            renderer.listeners.broadcast("deHiliteSegment", wayPointNum, objectID);
        }).bind("click", function(){
            renderer.listeners.broadcast("centerSegment", wayPointNum, objectID);
            return false;
        });
        $(childs).each(function(){
            this.id = 'route_segment_' + obj.id;
        });

        $(childs)[oddRow ? "addClass" : "removeClass"]("routing_odd_row");
        oddRow = !oddRow;
    }).add("status", function(s){
        if (s == "started") {
            $('.routing_content').trigger("routing:started");
        }
    });

    renderer.listeners.add("overSegment", function(w, s){
        $('#route_segment_' + s).addClass("active");
    }).add("outSegment", function(w, s){
        $('#route_segment_' + s).removeClass("active");
    });

    var routePoints = {
        savedTxt: {
            start: $('#startPoint').val(),
            end: $('#endPoint').val()
        },
        points: {},
        symbols: {
            start: "A",
            end: "B"
        },
        styles: {
            start: {
                color: "0091d5",
                alpha: 80
            },
            end: {
                color: "d82727",
                alpha: 80
            }
        },
        getLayerName: function(){
            if (!this.layer) {
                this.layer = "ROUTE_POINTS";
                ft.broadcastOnReady("layers.addSystemLayer", this.layer);
            }
            return this.layer;
        },
        setPoint: function(which, e, n, txt, center, noCenteringToRoute){
            this.points[which] = {
                e: e,
                n: n,
                txt: txt
            };
            txt = Regio.Utils.format("{0}:{1}", e, n);
            $('#' + which + 'Point').val(txt);

            if (center) {
                ft.broadcastOnReady("map.center", {
                    e: e,
                    n: n

                });
            }
            if (this.points.start && this.points.end) {
                this._startRoute([this.points.start, this.points.end], noCenteringToRoute);
            }
            ft.broadcastOnReady("layers.addPointToSystemLayer", this.getLayerName(), {
                objectId: which,
                geo: [{
                    e: e,
                    n: n
                }],
                color: this.styles[which].color,
                alpha: this.styles[which].alpha,
                symbolId: this.symbols[which],
                tooltip: txt
            });
        },
        clear: function(){
            $('#startPoint').val(this.savedTxt.start);
            $('#endPoint').val(this.savedTxt.end);
            this.points = [];
            route.stopRouting();
            route.clearPoints();
            ft.broadcastOnReady("layers.clearSystemLayer", this.getLayerName());
            //Regio._State.remove('rstart', 'rend');
        },
        swap: function(){
            var s = this.points['start'];
            var e = this.points['end'];
            if (s && e) {
                this.setPoint('start', e.e, e.n, e.txt);
                this.setPoint('end', s.e, s.n, s.txt);
            }
        },
        _startRoute: function(arr, noCenteringToRoute){
            route.stopRouting();
            route.clearPoints();
            route.addPoints(arr);
            route.startRouting(undefined, {
                noCentering: noCenteringToRoute
            });
        },
        isPointSet: function(n){
            return !!(this.points[n]);
        },
        getPointText: function(n){
            return this.points[n] ? this.points[n].txt : this.savedTxt[n];
        }
    };
    // install autocompletes
    var acProvider = Regio.SearchList.createAutocompleteProvider(env.PARAM_regio.user, {
        srs: 'epsg:4326'
    });
    Regio.Autocomplete($('#startPoint').click(function(){
        $(this).val('')
    }).blur(function(){
        $(this).val(routePoints.getPointText('start'))
    }), acProvider.uri, jQuery.extend(acProvider, {
        onItemSelect: function(li){
            routePoints.setPoint('start', li.extra[0].point.coordinates[0], li.extra[0].point.coordinates[1], li.extra[0].address, !routePoints.isPointSet('end'), !routePoints.isPointSet('end'));
        }
    }));
    Regio.Autocomplete($('#endPoint').click(function(){
        $(this).val('')
    }).blur(function(){
        $(this).val(routePoints.getPointText('end'))
    }), acProvider.uri, jQuery.extend(acProvider, {
        onItemSelect: function(li){
            routePoints.setPoint('end', li.extra[0].point.coordinates[0], li.extra[0].point.coordinates[1], li.extra[0].address, !routePoints.isPointSet('start'), !routePoints.isPointSet('start'));
        }
    }));

    ft.addCallback("routing.startPointFixed", function(args, noCenteringToRoute){
        noCenteringToRoute = !routePoints.isPointSet('end');
        routePoints.setPoint("start", (args.lon ? args.lon : args.e), (args.lat ? args.lat : args.n), args.locationName, args.center, noCenteringToRoute);
        ft.broadcastOnReady("layers.removeSystemLayer", "_ROUTE_POINTS"); // remove FT buildin routing doings
    });

    ft.addCallback("routing.endPointFixed", function(args, noCenteringToRoute){
        noCenteringToRoute = !routePoints.isPointSet('start');
        routePoints.setPoint("end", (args.lon ? args.lon : args.e), (args.lat ? args.lat : args.n), args.locationName, args.center, noCenteringToRoute);
        ft.broadcastOnReady("layers.removeSystemLayer", "_ROUTE_POINTS"); // remove FT buildin routing doings
    });

    ft.addCallback("routing.clear", function(){
        routePoints.clear();
    });

    // html bindings
    $('.route_message').hide();

    (function(){
        $a = $(".routingAButton");
        $b = $(".routingBButton");
        var active = "active"; // class :hover
        $a.click(function(){
            if ($a.hasClass(active)) {
                $a.removeClass(active);
                ft.broadcastOnReady('ft.stopEditMode');
            }
            else {
                $a.addClass(active);
                $b.removeClass(active);
                ft.broadcastOnReady('routing.placeRouteStartPoint');
            }
            return false;
        });
        $b.click(function(){
            if ($b.hasClass(active)) {
                $b.removeClass(active);
                ft.broadcastOnReady('ft.stopEditMode');
            }
            else {
                $b.addClass(active);
                $a.removeClass(active);
                ft.broadcastOnReady('routing.placeRouteEndPoint');
            }
            return false;
        });
        var deselect = function(){
            $a.removeClass(active);
            $b.removeClass(active);
        }
        ft.addCallback("routing.endPointFixed", deselect);
        ft.addCallback("routing.startPointFixed", deselect);
    })();

    $('.routingSwapButton').click(function(){
        routePoints.swap();
        return false;
    });

    $('.start_routing').click(function(){
        route.startRouting();
        return false;
    }).attr('href', '#');

    $('.stop_routing').click(function(){
        route.stopRouting();
        return false;
    }).attr('href', '#');

    $('.clear_route_points').click(function(){
        routePoints.clear();
        return false;
    }).attr('href', '#');

    route.clearAll = function(){
        routePoints.clear();
    }
    route.routePoints = routePoints;
    return route;
}


Regio._Modules['layers'] = function(){
    var $div = $('[wrapperForTemplate=layers]');

    LoadPage($div, "templates/layers.html", ".templateBody", function(){
        var adapter = new Regio.Controls.LayersTree.FlashTileAdapter(Regio._Map);

        Regio._LayersTree = new Regio.Controls.LayersTree('layers-tree', adapter, {
            sortable: true
        });

        Regio._Map.addCallback('layer.loaded', function(args){
            Regio._addOnClick(args);
        });

        var menuData = Regio._Map.call("mapcat.layersData.get");
        if (menuData) {
            Regio._Map.broadcast("mapcat.layersData.loaded", menuData);
        }

    });
}

/*
 Module: PageLoader
 Downloads and injects HTML into specified selector.
 Requires: jQuery
 Author:
 Alexandr Smirnov (alex@regio.ee)
 */
function LoadPage(where, url, selector, callback){
    var url = env.PARAM_regio.templates_static_prefix + url;

    callback = callback ||
    function(){
    };

    // Request the remote document
    var ajax = jQuery.ajax({
        url: url,
        type: "GET",
        dataType: "html",
        complete: function(res, status){
            if (status == "success" || status == "notmodified") {
                var contents = res.responseText;

                // See if a selector was specified
                if (selector) {
                    // Create a dummy div to hold the results
                    jQuery(where).html(jQuery("<div/>").append(contents).find(selector));
                }
                else {
                    // If not, just inject the full result
                    jQuery(where).html(contents);
                };

                callback();
            }
        }
    });
    return ajax;
}
