



var Map = (function(dojo) {

    dojo.require("esri.map");
    dojo.require("esri.toolbars.draw");
    dojo.require("esri.dijit.Popup");
    dojo.require("dijit.TooltipDialog");

    var mapLoaded = false,
        mapSet = false,
        resultMapLoaded = false,
        resultMapSet = false;

    var automaticExtent = true;

	var defaultExtentIncludePoints = [{x: 3514288.076, y: 6841801.178}, {x: 3514289.076, y: 6841802.178}];
    var dataSpatialRef;
    var projectionService;

    var map, resultMap, dialog;
    var fullExtent;

    var invoices = [];
    var consumers = [];

    

    var isConsumer = function(id, invoice) {
        return invoice != '' && invoice !== id;
    }

    var isSelected = function(id, invoice) {
        var multiSelect;
        if(isConsumer(invoice)) {
            multiSelect = $("#consumers-multiselect").data("kendoMultiSelect");
        } else {
            multiSelect = $("#invoices-multiselect").data("kendoMultiSelect");
        }
        return multiSelect.value().indexOf(id) > -1;
    }

    var isTerminated = function(endDate)
    {
        return endDate !== null;
    }

    var insertNewSelection = function(graphic) {
        var multiSelect;
        if (isConsumer(graphic.attributes.id, graphic.attributes.invoice)) {
            // update consumer selector
            if($("#consumers-multiselect").closest('.form-group').is(':visible')) {
                multiSelect = $("#consumers-multiselect").data("kendoMultiSelect");
            }
        } else {
            // update invoice selector
            multiSelect = $("#invoices-multiselect").data("kendoMultiSelect");
        }
        var ids = [];
        if (multiSelect != null){
            dojo.forEach(multiSelect.value(), function(id) {
                ids.push(id);
            });
        }
        if (dojo.indexOf(ids, graphic.attributes.id) == -1) {
            ids.push(graphic.attributes.id);
            if (multiSelect != null)
            {
                multiSelect.value(ids);
                multiSelect.trigger('change');
            }
        }
    }

    var checkAndFixMapExtent = function(_map) {

        var deltaX = 0;
        var deltaY = 0;

        if (fullExtent != null)
        {
            // Korjaa vain jos kokonaan alueen ulkopuolella, muuten ainakin esrin kartta saattaa ruveta 'heilumaan'
            if (_map.extent.xmax <  fullExtent.xmin || fullExtent.xmax < _map.extent.xmin)
            {
                if (_map.extent.xmin < fullExtent.xmin) {
                    deltaX = fullExtent.xmin - _map.extent.xmin;
                } else if (_map.extent.xmax > fullExtent.xmax) {
                    deltaX = fullExtent.xmax - _map.extent.xmax;
                }
            }

            if (_map.extent.ymax <  fullExtent.ymin || fullExtent.ymax < _map.extent.ymin)
            {
                if (_map.extent.ymin < fullExtent.ymin) {
                    deltaY = fullExtent.ymin - _map.extent.ymin;
                } else if (_map.extent.ymax > fullExtent.ymax) {
                    deltaY = fullExtent.ymax - _map.extent.ymax;
                }
            }
        }

        if (deltaX != 0 || deltaY != 0)
            _map.setExtent(new esri.geometry.Extent(
                _map.extent.xmin + deltaX,
                _map.extent.ymin + deltaY,
                _map.extent.xmax + deltaX,
                _map.extent.ymax + deltaY,
                _map.spatialReference));
    }

    var addPointsToMap = function(data, successCallback, onProjected) {
        if (data.length > 0) {
            // Lisää pisteet kartalle
            addPointsFromCustomer($.grep(data, function(value) {
                return value.x > 0 && value.y > 0;
            }), successCallback, onProjected);
        }
    }

    // Tekee customer-objekteista kartalle lisättävät pisteet.
    var addPointsFromCustomer = function(customers, successCallback, onProjected) {
        var unprojectedPoints = [];
        for (var i = 0; i < customers.length; ++i) {
            unprojectedPoints.push(new esri.geometry.Point(customers[i].x, customers[i].y, dataSpatialRef));
        }

        if (unprojectedPoints.length > 0) {
            project(projectionService, unprojectedPoints, map)
            .then(function(projectedPoints) {
                if(onProjected) {
                    onProjected(projectedPoints);
                }

                for (var i = 0; i < projectedPoints.length; ++i) {

                    var symbolColor = isConsumer(customers[i].id, customers[i].invoice)
                        ? new esri.Color([225, 119, 42, 1])
                        : new esri.Color([53, 126, 189, 1]);
                    var outlineColor = isSelected(customers[i].id, customers[i].invoice)
                        ? new esri.Color([255, 255, 0, 1])
                        : new esri.Color([0, 0, 0, 1]);

                    var endDateText = "";

                    if (isTerminated(customers[i].endDate))
                    {
                        var a = 0.333;
                        symbolColor.a = a;
                        outlineColor.a = a;
                        endDateText = "| " + "Loppunut"  + " " + moment(customers[i].endDate).format('DD.MM.YYYY');
                    }

                    var point = {
                        geometry: {
                            x: projectedPoints[i].x,
                            y: projectedPoints[i].y,
                            spatialReference: {
                                wkid: map.spatialReference.wkid
                            }
                        },
                        attributes: {
                            id: customers[i].id,
                            invoice: customers[i].invoice,
                            name: customers[i].name.split("|")[0],
                            address: customers[i].address,
                            endDateText: endDateText
                        },
                        symbol: {
                            color: symbolColor,
                            size: 15,
                            angle: 0,
                            xoffset: 0,
                            yoffset: 0,
                            type: 'esriSMS',
                            style: 'esriSMSCircle',
                            outline: {
                                color: outlineColor,
                                width: 1,
                                type: 'esriSLS',
                                style: 'esriSLSSolid'
                            }
                        }
                    };
                    map.graphics.add(new esri.Graphic(point));
                }
                successCallback();
            });
        }
    }

    var getExtentFromMapPoints = function(_map) {
        var xmin, xmax, ymin, ymax;
        $.each(_map.graphics.graphics, function(index, graphic) {
            if (index == 0) {
                xmin = graphic.geometry.x;
                xmax = graphic.geometry.x;
                ymin = graphic.geometry.y;
                ymax = graphic.geometry.y;
            } else {
                if (xmin > graphic.geometry.x && graphic.geometry.x > 0) {
                    xmin = graphic.geometry.x;
                }
                if (xmax < graphic.geometry.x && graphic.geometry.x > 0) {
                    xmax = graphic.geometry.x;
                }
                if (ymin > graphic.geometry.y && graphic.geometry.y > 0) {
                    ymin = graphic.geometry.y;
                }
                if (ymax < graphic.geometry.y && graphic.geometry.y > 0) {
                    ymax = graphic.geometry.y;
                }
            }
        });

        return new esri.geometry.Extent(xmin, ymin, xmax, ymax, _map.spatialReference);
    }

    var clearSearchMap = function() {
        map.graphics.clear();
    }

    
    
    var searchMapFunctions = {
        init: function(loadPoints) {
            map = new esri.Map("map", {
                sliderStyle: "small",
                showInfoWindowOnClick: false,
                logo: false,
                minZoom: 1,
                autoResize: true,
                
            });

            var tileLayer = new esri.layers.ArcGISTiledMapServiceLayer(mapUrl);
            map.addLayer(tileLayer);

            // Pisteiden vienti kartalle täytyy tehdä
            // vasta kun kartta on latautunut.
            dojo.connect(map, "onLoad", function() {
                var defaultPoints = [];
                for (var i = 0; i < defaultExtentIncludePoints.length; ++i) {
                    defaultPoints.push(new esri.geometry.Point(defaultExtentIncludePoints[i].x, defaultExtentIncludePoints[i].y, dataSpatialRef));
                }

                map.reposition();
                map.resize(true);
    
                project(projectionService, defaultPoints, map)
                .then(function(projectedPoints) {
                    if(projectedPoints.length > 1) {
                        var extent = getExtentFromPoints(projectedPoints, map.spatialReference);
                        map.setExtent(extent.expand(50000));
                    } else {
                        map.setScale(100000 * 50000);
                        map.centerAt(projectedPoints[0]);
                    }
                });
                
                mapLoaded = true;

                fullExtent = tileLayer.fullExtent;

                dojo.connect(map.graphics, "onMouseOver", function(event) {
                    map.setMapCursor("pointer");
                });

                dojo.connect(map.graphics, "onMouseOut", function(event) {
                    map.setMapCursor("default");
                });

                dojo.connect(map, "onClick", function(event) {
                    if (event.graphic) {
                        automaticExtent = false;
                        insertNewSelection(event.graphic);
                    }
                });

                dojo.connect(map, "onExtentChange", function(extent, delta, levelChange, lod) {
                    checkAndFixMapExtent(map);
                });

                dialog = new dijit.TooltipDialog({
                    id: 'tooltipDialog',
                    style: 'position: absolute; width: auto; font: normal normal normal 10pt Helvetica;z-index:100'
                });
                dialog.startup();

                dojo.connect(map.graphics, 'onMouseOver', function(event) {
                    if(!event.graphic)
                        return;

                    var t = "${name} | ${id} | ${address} ${endDateText}";
                    var content = esri.substitute(event.graphic.attributes, t);
                    dialog.setContent(content);
                    dijit.popup.open({
                        popup: dialog,
                        x: event.pageX,
                        y: event.pageY
                    });
                });
                dojo.connect(map.graphics, 'onMouseOut', function(event) {
                    dijit.popup.close(dialog);
                });

                loadPoints();
            });

            dataSpatialRef = new esri.SpatialReference({
                wkid: 2393
            });
            projectionService = new esri.tasks.GeometryService("https://arcgis2.tietomitta.com/arcgis/rest/services/Utilities/Geometry/GeometryServer");
        },
        
        setAutomaticExtent: function(value) {
            automaticExtent = value;
        },

        addInvoicesAndCustomers: function(points) {
            var invoices = [];
            var customers = [];

            if(!!points.invoices) {
                invoices = points.invoices.slice();
            }
            if(!!points.customers) {
                customers = points.customers.slice();
            }

            if (typeof('map') == 'undefined' || map == null || !('graphics' in map) || map.graphics == null) return;

            var all = invoices.concat(customers);
            if(all.length > 0) {
                addPointsToMap(all, function() {
                    if(!automaticExtent)
                        return;

                    // if any point added to map set new extent.
                    var extent = getExtentFromMapPoints(map);
                    // expand a little so the points on the edge can be seen better.
                    map.setExtent(extent.expand(1.5));
                }, function() {
                    clearSearchMap();
                });
            } else {
                clearSearchMap();
            }
        },

        clearSearchMap: clearSearchMap,

        resize: function(immediate) {
            map.resize(immediate);
        }
    };
    
    

    return $.extend(searchMapFunctions, {
        checkAndFixMapExtent: checkAndFixMapExtent,
        getExtentFromMapPoints: getExtentFromMapPoints,

        isValidPoint: function(point) {
            return point.x && point.y && point.x > 0 && point.y > 0;
        }
    });

})(dojo);