﻿// object for displaying MapTips
geodata.maptips.MapTipsLayer = function(map) {
    this.id = "GDMapTips";
    this.overlapGridCellWidth = 60;
    this.overlapGridCellHeight = 60;
    this.alwaysShowWeatherWithPriorityLowerThan = 24;
    this.containerId = null;
    this.map = map;
    this.enabled = true;
    this.mapTipItems = [];
    this.weatherItems = [];
    this.iconFont = new esri.symbol.Font("11px",
	    esri.symbol.Font.STYLE_NORMAL,
	    esri.symbol.Font.VARIANT_NORMAL,
	    esri.symbol.Font.WEIGHT_NORMAL,
	    "Verdana");
	this.iconFontHalo = new esri.symbol.Font("10px",
	    esri.symbol.Font.STYLE_NORMAL,
	    esri.symbol.Font.VARIANT_NORMAL,
	    esri.symbol.Font.WEIGHT_NORMAL,
	    "Verdana");
	this.iconFontLight = new esri.symbol.Font("10px",
	    esri.symbol.Font.STYLE_NORMAL,
	    esri.symbol.Font.VARIANT_NORMAL,
	    esri.symbol.Font.WEIGHT_NORMAL,
	    "Verdana");
	    	    
    this.iconTextColor = new dojo.Color([255, 255, 255]);
    this.operaTextColor = new dojo.Color([32, 197, 237]);
    this.temperatureTextColor= new dojo.Color("#575859");
    this.selectedMapTipItem = null;
    this.weatherInfoTemplate = null;

    this.setupInfoWindow = function() {
        var heading = gdGetText("/map/weather/weatherheading");
        var tooltip = gdGetTooltip("/weather/detailedforecast").replace("{0}", "${LocationName}");
        var linktext = gdGetText("/weather/detailedforecast");
        this.weatherInfoTemplate = new esri.InfoTemplate(
            "<div class=\"c_map_weatherheading\">" + heading + "</div>" +
            "<div class=\"c_map_weatherlocation\">${LocationName}</div>",
            "<div class=\"c_map_weatherforecast\">" +
            "  <div class=\"c_map_forecast_container\">${forecastHtml}</div> " +
            "  <div class=\"c_map_detailedforecast\">" +
            "    <a title=\"" + tooltip + "\" target=\"_blank\" href=\"${yrUrl}\"><img title=\"" + tooltip + "\" alt=\"\" src=\"/images/icons/vn_external_gray.png\" class=\"leftfloating noborder\"/><span>" + linktext + "</span></a>" +
            "  </div>" +
            "</div>");
        this.map.infoWindow.resize(210, 247);
        dojo.connect(this.map.infoWindow, "onShow", function() {
            var infoLayer = gdMap.infoWindow.domNode; //dojo.byId("gdMapDiv_infowindow");
            infoLayer.style.cssText = ("" + infoLayer.style.cssText).replace("z-index: 40;", "z-index: 40000;");
            if (gdMap.infoWindow.anchor == esri.dijit.InfoWindow.ANCHOR_UPPERRIGHT || gdMap.infoWindow.anchor == esri.dijit.InfoWindow.ANCHOR_UPPERLEFT) {
                //dojo.style(gdMap.infoWindow._window, "top", "20px");
                //dojo.style(gdMap.infoWindow._pointer, "top", "200px");
            }
            else {
                dojo.style(gdMap.infoWindow._window, "top", "20px");
            }
        });
        dojo.connect(this.map.infoWindow, "onHide", function() {
            var infoLayer = dojo.byId("gdMapDiv_infowindow");
            infoLayer.style.cssText = "display: none;z-index: 40;";
        });
    }

    this.getWeatherForecastText = function(wdi) {
        var symbolNumber = 0;
        if (wdi.SymbolNumber > 0 && wdi.SymbolNumber < 16) {
            symbolNumber = wdi.SymbolNumber;
        }
        else if (wdi.SymbolNumber == 16) {
            symbolNumber = 1;
        }
        else if (wdi.SymbolNumber == 17) {
            symbolNumber = 3;
        }
        else if (wdi.SymbolNumber == 18) {
            symbolNumber = 5;
        }
        else if (wdi.SymbolNumber == 19) {
            symbolNumber = 8;
        }
        var retVal = gdGetText("/weather/weather" + symbolNumber);
        if (wdi.WindSpeed > 0) {
            retVal += ", " + gdGetText("/weather/wind" + this.getWindSpeedId(wdi.WindSpeed));
        }
        return retVal;
    }

    this.getWindSpeedId = function(ws) {
        var retVal;
        if (ws < 0.3)
            retVal = 1;
        else if (ws < 1.6)
            retVal = 2;
        else if (ws < 3.4)
            retVal = 3;
        else if (ws < 5.5)
            retVal = 4;
        else if (ws < 8.0)
            retVal = 5;
        else if (ws < 10.8)
            retVal = 6;
        else if (ws < 13.9)
            retVal = 7;
        else if (ws < 17.2)
            retVal = 8;
        else if (ws < 20.8)
            retVal = 9;
        else if (ws < 24.5)
            retVal = 10;
        else if (ws < 28.5)
            retVal = 11;
        else if (ws < 32.6)
            retVal = 12;
        else
            retVal = 13;
        return retVal;
    }

    this.addOperaWorkaround = function(item) {
        var padLen = Math.ceil(item.icon.defaultIcon.width / 10);
        if (padLen < 1) padLen = 1;
        var text = "_";
        while (--padLen > 0) text = text + "_";
        var g = new esri.geometry.Point(item.X, item.Y, null);
        var s = new esri.symbol.TextSymbol(text, this.iconFont, this.operaTextColor);
        s.setAlign(esri.symbol.TextSymbol.ALIGN_MIDDLE);
        s.setOffset(0, 0);
        var gr = new esri.Graphic(g, s, { index: item.index, selected: item.selected }, null);
        this.map.graphics.add(gr);
    }

    this.addOperaWorkaroundWeather = function(gr) {
        var s = new esri.symbol.TextSymbol("____", this.iconFont, this.operaTextColor);
        s.setAlign(esri.symbol.TextSymbol.ALIGN_MIDDLE);
        s.setOffset(0, 0);
        this.map.graphics.add(new esri.Graphic(gr.geometry, s, gr.attributes, this.weatherInfoTemplate));
        this.map.graphics.add(new esri.Graphic(gr.geometry, gr.symbol, {}, null));
    }

    this.addMapTipImage = function(item) {
        var g = new esri.geometry.Point(item.X, item.Y, null);
        var s = new esri.symbol.PictureMarkerSymbol(item.icon.defaultIcon.url, item.icon.defaultIcon.width, item.icon.defaultIcon.height);
        //var s = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_DIAMOND, 20, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0,0,0]), 1), new dojo.Color([255,255,0,0.5]));
        var gr = new esri.Graphic(g, s, { index: item.index, selected: item.selected }, null);
        this.map.graphics.add(gr);
    }

    this.addMapTipText = function(item) {
        var text = item.iconHtml;
        if (text != null) {
            text = text.replace("&nbsp;&nbsp;", "");
            if (text != "") {
                var g = new esri.geometry.Point(item.X, item.Y, null);
                var s = new esri.symbol.TextSymbol(text, this.iconFont, this.iconTextColor);
                s.setAlign(esri.symbol.TextSymbol.ALIGN_MIDDLE);
                if (dojo.isIE)
                    s.setOffset(4, 3);
                else
                    s.setOffset(4, 1);
                var gr = new esri.Graphic(g, s, { index: item.index, selected: item.selected }, null);
                this.map.graphics.add(gr);
            }
        }
    }

    this.addMapTips = function(items, selectedItem) {
        this.hideCurrentItem();
        this.mapTipItems = items;
        this.selectedMapTipItem = selectedItem;
        this.updateGraphics();
    }

    this.updateGraphics = function() {
        this.map.graphics.clear();
        var previousId = null;
        var overlapGrid = [];
        var ogw = Math.ceil(this.map.width / this.overlapGridCellWidth) + 2;
        var ogh = Math.ceil(this.map.height / this.overlapGridCellHeight) + 2;
        for (var x = 0; x < ogw; x++) {
            overlapGrid[x] = [];
            for (var y = 0; y < ogh; y++) {
                overlapGrid[x][y] = false;
            }
        }
        
        dojo.forEach(this.mapTipItems, function(item) { item.selected = false; });
        if (dojo.isOpera) {
            // Mouseover doesn't work for picturemarkers in Opera, so we add a text symbol
            // to cover the picture marker and give us the mouseover effect.
            dojo.forEach(this.mapTipItems, this.addOperaWorkaround, this);
        }
        dojo.forEach(this.mapTipItems, this.addMapTipImage, this);
        dojo.forEach(this.mapTipItems, this.addMapTipText, this);
        if (this.selectedMapTipItem) {
            this.selectedMapTipItem.selected = true;
            if (dojo.isOpera) this.addOperaWorkaround(this.selectedMapTipItem);
            this.addMapTipImage(this.selectedMapTipItem);
            this.addMapTipText(this.selectedMapTipItem);
        }
        this.map.graphics.enableMouseEvents();
        
        
        dojo.forEach(this.weatherItems, function(item) {
            var forecastHtml = "";
            var count = 0;
            var currentTime = new Date();
            var symbolFc = null;
            var arrTempSymbOffset;
            var xoppset;
            var yoffset;
            
            //var symbolFcTemperature = null;
            
            dojo.forEach(item.forecasts, function(fc) {
                if (count < 4 && fc.Period == 2) {
                    var d = this.parseDate(fc.From);
                    if (currentTime.getFullYear() < d.getFullYear() || currentTime.getMonth() < d.getMonth() || currentTime.getDate() < d.getDate()) {
                        if (symbolFc == null) symbolFc = fc;
                        forecastHtml += this.createForecastHtml(fc, d);
                        count++;
                    }
                }
            }, this);
            if (symbolFc != null) {
            
            
                var g = new esri.geometry.Point(item.Longitude, item.Latitude, null);
                var s = new esri.symbol.PictureMarkerSymbol(this.getSymbolUrl(symbolFc, true), 43, 43);
                var gr = new esri.Graphic(g, s, { LocationName: item.LocationName, forecastHtml: forecastHtml, yrUrl: this.getYrUrl(item) }, this.weatherInfoTemplate);
                var sp = this.map.toScreen(gr.geometry);
                
                              

 


                 
                var x = Math.floor(sp.x / this.overlapGridCellWidth);
                var y = Math.floor(sp.y / this.overlapGridCellHeight);
                if (this.checkOverlap(x, y, overlapGrid, item.Priority)) {
                    if (dojo.isOpera) {
                        // Mouseover doesn't work for picturemarkers in Opera, so we add a text symbol
                        // to cover the picture marker and give us the mouseover effect.
                        this.addOperaWorkaroundWeather(gr);
                    }
                    else {
                        this.map.graphics.add(gr);
                        
                        //var sTemperature = new esri.symbol.PictureMarkerSymbol(this.getTemperatureSymbolUrl(symbolFc, true), 43, 43);
//                        var symTemp = new esri.symbol.PictureMarkerSymbol(this.getSymbolUrl(symbolFc, true), 43, 43);
//                        var geoScrTemp = this.map.toScreen(g);
//                        geoScrTemp.offset(10,0);
//                        var geoMapTemp = this.map.toMap(geoScrTemp);            
//                        var grTemp = new esri.Graphic(geoMapTemp, symTemp, { LocationName: item.LocationName, forecastHtml: forecastHtml, yrUrl: this.getYrUrl(item) }, this.weatherInfoTemplate);
                        //var spTemp = this.map.toScreen(grTemp.geometry);                
                
                        //var symTxtTemperature = new esri.symbol.TextSymbol(this.getTemperature(item), this.iconFont, this.operaTextColor);                              
                        //esri.symbol.Font(size, style, variant, weight, family)
                        
                        arrTempSymbOffset = this.getTemperatureSymbolOffset(symbolFc,false);
                        xoffset = arrTempSymbOffset[0];
                        yoffset = arrTempSymbOffset[1];
                        
                        var nHaloWidth = 1;
                        
                        
                        var symTxtTemperatureHalo1 = new esri.symbol.TextSymbol(this.getTemperatureNoPostFix(symbolFc), this.iconFontHalo, new dojo.Color("white"));
                        symTxtTemperatureHalo1.setAlign(esri.symbol.TextSymbol.ALIGN_MIDDLE);
                        symTxtTemperatureHalo1.setOffset(xoffset-nHaloWidth,yoffset-nHaloWidth);
                        //this.map.graphics.add(new esri.Graphic(gr.geometry, symTxtTemperatureHalo1, null, null));
                        var grTextHalo1 = new esri.Graphic(g, symTxtTemperatureHalo1, { LocationName: item.LocationName, forecastHtml: forecastHtml, yrUrl: this.getYrUrl(item) }, this.weatherInfoTemplate);
                        this.map.graphics.add(grTextHalo1);
                        
                        var symTxtTemperatureHalo2 = new esri.symbol.TextSymbol(this.getTemperatureNoPostFix(symbolFc), this.iconFontHalo, new dojo.Color("white"));
                        symTxtTemperatureHalo2.setAlign(esri.symbol.TextSymbol.ALIGN_MIDDLE);
                        symTxtTemperatureHalo2.setOffset(xoffset-nHaloWidth,yoffset+nHaloWidth);
                        //this.map.graphics.add(new esri.Graphic(gr.geometry, symTxtTemperatureHalo2, null, null));
                        var grTextHalo2 = new esri.Graphic(g, symTxtTemperatureHalo2, { LocationName: item.LocationName, forecastHtml: forecastHtml, yrUrl: this.getYrUrl(item) }, this.weatherInfoTemplate);
                        this.map.graphics.add(grTextHalo2);
                                                
                        var symTxtTemperatureHalo3 = new esri.symbol.TextSymbol(this.getTemperatureNoPostFix(symbolFc), this.iconFontHalo, new dojo.Color("white"));
                        symTxtTemperatureHalo3.setAlign(esri.symbol.TextSymbol.ALIGN_MIDDLE);
                        symTxtTemperatureHalo3.setOffset(xoffset+nHaloWidth,yoffset-nHaloWidth);
                        //this.map.graphics.add(new esri.Graphic(gr.geometry, symTxtTemperatureHalo3, null, null));
                        var grTextHalo3 = new esri.Graphic(g, symTxtTemperatureHalo3, { LocationName: item.LocationName, forecastHtml: forecastHtml, yrUrl: this.getYrUrl(item) }, this.weatherInfoTemplate);
                        this.map.graphics.add(grTextHalo3);
                        
                        
                        var symTxtTemperatureHalo4 = new esri.symbol.TextSymbol(this.getTemperatureNoPostFix(symbolFc), this.iconFontHalo, new dojo.Color("white"));
                        symTxtTemperatureHalo4.setAlign(esri.symbol.TextSymbol.ALIGN_MIDDLE);
                        symTxtTemperatureHalo4.setOffset(xoffset+nHaloWidth,yoffset+nHaloWidth);
                        //this.map.graphics.add(new esri.Graphic(gr.geometry, symTxtTemperatureHalo4, null, null));
                        var grTextHalo4 = new esri.Graphic(g, symTxtTemperatureHalo4, { LocationName: item.LocationName, forecastHtml: forecastHtml, yrUrl: this.getYrUrl(item) }, this.weatherInfoTemplate);
                        this.map.graphics.add(grTextHalo4);
                        
                        
                          
                        var symTxtTemperature = new esri.symbol.TextSymbol(this.getTemperatureNoPostFix(symbolFc), this.iconFontLight, this.temperatureTextColor);
                        symTxtTemperature.setAlign(esri.symbol.TextSymbol.ALIGN_MIDDLE);
                        symTxtTemperature.setOffset(xoffset,yoffset);
                        
                        //this.map.graphics.add(new esri.Graphic(gr.geometry, symTxtTemperature, null, null));
                        
                        var grTextTemp = new esri.Graphic(g, symTxtTemperature, { LocationName: item.LocationName, forecastHtml: forecastHtml, yrUrl: this.getYrUrl(item) }, this.weatherInfoTemplate);
                        this.map.graphics.add(grTextTemp);
                       
                        
                        //this.map.graphics.add(new esri.Graphic(gr.geometry, gr.symbol, {}, null));
                        //this.map.graphics.add(grTemp);
                    }
                }
            }
        }, this);
 
    }

    this.checkOverlap = function(x, y, overlapGrid, priority) {
        if (priority >= this.alwaysShowWeatherWithPriorityLowerThan) {
            for (var i = x - 1; i < x + 1; i++)
                for (var j = y - 1; j < y + 1; j++)
                if (i >= 0 && j >= 0 && i < overlapGrid.length && j < overlapGrid[i].length && overlapGrid[i][j])
                return false;
        }
        for (var i = x - 1; i < x + 1; i++)
            for (var j = y - 1; j < y + 1; j++)
            if (i >= 0 && j >= 0 && i < overlapGrid.length && j < overlapGrid[i].length)
            overlapGrid[i][j] = true;
        return true;
    }

    this.getDayString = function(dayNumber) {
        return gdGetText("/map/weather/weekday" + dayNumber);
    }

    this.getTemperature = function(weatherForecast) {
        if (gdClientData.languageCode.toLowerCase() == "en-us")
            return Math.round(((9.0 / 5.0) * weatherForecast.Temperature) + 32) + "°F";
        else
            return weatherForecast.Temperature + "°C";
    }
    
    this.getTemperatureNoPostFix = function(weatherForecast) {
        if (gdClientData.languageCode.toLowerCase() == "en-us")
            return Math.round(((9.0 / 5.0) * weatherForecast.Temperature) + 32) + "°";
        else
            return weatherForecast.Temperature + "°";
    }

    this.getYrUrl = function(weatherLocation) {
        if (gdClientData.languageCode == "no")
            return weatherLocation.NBUrl.replace("varsel.xml", "")
        else
            return weatherLocation.ENUrl.replace("forecast.xml", "")
    }

    this.getSymbolUrl = function(weatherForecast, shadow) {
        var suffix = ""; if (shadow) suffix = "_s";
        var url = weatherForecast.SymbolNumber + (weatherForecast.Period == 0 ? "n" : "d") + suffix + ".png";
        while (url.length < ("00n" + suffix + ".png").length) url = "0" + url;
        if (shadow)
            return "/images/icons/weather_small_shadow/" + url;
        else
            return "/images/icons/weather/" + url;
    }
    
    this.getTemperatureSymbolOffset = function(weatherForecast, shadow) {
        var xoffset;
        var yoffset;
        var result= new Array();
        
        switch(weatherForecast.SymbolNumber)
        {
        case 1:
        case 2:
            xoffset = -1;
            yoffset = -3;
            break;
        case 3:
            xoffset = -5;
            yoffset = -6;
            break;        
        case 4:         
            xoffset = -1;
            yoffset = -7;
            break;        
        case 5:
        case 6:
        case 7:
        case 8:        
            xoffset = -5;
            yoffset = -6;
            break;          
        case 9:
        case 10:
        case 11:
        case 12:
        case 13:
        case 14:           
            xoffset = -2;
            yoffset = -0;
            break;
        case 15:
            xoffset = -2;
            yoffset = -3;
            break;        
        case 16:
            xoffset = -2;
            yoffset = 2;
            break;        
        case 17:
        case 18:
        case 19:
            xoffset = -2;
            yoffset = 4;        
            break;
//        case 99:        
//        if (weatherForecast.Period == "d") {
//                xoffset = 0;
//                yoffset=0;
//            }
//            else {
//                xoffset = 0;
//                yoffset=0;            
//            }
//            break;
        default:
            xoffset = -2;
            yoffset = -3;
        }
        result[0]=xoffset;
        result[1]=yoffset;
        return result;
    }
    
    this.getTemperatureSymbolUrl = function(weatherForecast, shadow) {
        var temperature;
        temperature = this.getTemperature(weatherForecast);
        
        
//        var suffix = ""; if (shadow) suffix = "_s";
//        var url = weatherForecast.SymbolNumber + (weatherForecast.Period == 0 ? "n" : "d") + suffix + ".png";
//        while (url.length < ("00n" + suffix + ".png").length) url = "0" + url;
//        if (shadow)
//            return "/images/icons/weather_small_shadow/" + url;
//        else
//            return "/images/icons/weather/" + url;
    }

    this.createForecastHtml = function(weatherForecast, d) {
        var html = "";
        var tooltip = this.getWeatherForecastText(weatherForecast) + " (" + gdGetText("/weather/time/atnoon") + ")";
        html += "    <div class=\"c_map_forecast\">";
        html += "      <div class=\"weather_day\">";
        html += "        <span>" + this.getDayString(d.getDay()) + "</span>";
        html += "      </div>";
        html += "      <div class=\"weather_symbol\">";
        html += "        <img alt=\"" + tooltip + "\" title=\"" + tooltip + "\" src=\"" + this.getSymbolUrl(weatherForecast) + "\"/>";
        html += "      </div>";
        html += "      <div class=\"weather_temp\">";
        html += "        <span>" + this.getTemperature(weatherForecast) + "</span>";
        html += "      </div>";
        html += "    </div>";
        return html;
    }

    this.parseDate = function(dateString) {
        //"04/29/2009 06:00:00"
        var s = dateString.split(" ");
        var datePart = s[0];
        var timePart = s[1];
        var dateParts = datePart.split("/");
        var timeParts = timePart.split(":");
        var result = new Date();
        result.setFullYear(dateParts[2] * 1);
        result.setMonth(dateParts[0] * 1 - 1, dateParts[1] * 1);
        result.setHours(timeParts[0] * 1, timeParts[1] * 1, timeParts[2] * 1, 0);
        return result;
    }

    this.addWeather = function(weatherForecasts) {
        if (this.weatherInfoTemplate == null) this.setupInfoWindow();
        var weatherItems = [];
        var wLen = 0;
        // Gather all forecasts for same locationid in one object
        for (var i = 0, len = weatherForecasts.length; i < len; i++) {
            var fc = weatherForecasts[i];
            if (wLen == 0 || weatherItems[wLen - 1].locationId != fc.locationId) {
                wLen++;
                fc.forecasts = [];
                weatherItems.push(fc);
                fc.forecasts.push(fc);
            }
            else
                weatherItems[wLen - 1].forecasts.push(fc);
        }
        this.weatherItems = weatherItems;
        this.updateGraphics();
    }

    this.getMapTip = function(index) {
        for (var i = 0, len = this.mapTipItems.length; i < len; i++) {
            var item = this.mapTipItems[i];
            if (item.index == index) return item;
        }
        return null;
    }

    this.showTip = function(index, e, productID, selected) {
        var item = null;
        if (this.enabled) {
            if (selected)
                item = this.selectedMapTipItem;
            else
                item = this.getMapTip(index);
            if (item == null && this.selectedMapTipItem != null && this.selectedMapTipItem.index == index)
                item = this.selectedMapTipItem;
            geodata.maptips.currentMapTipsWindow.show(item);
        }
        if (productID && productID >= 0) {
            var multilist_content = document.getElementById('c_mapmultilistview_content_' + index);
            if (multilist_content) {
                // "Flat" list map tip, highlight correct product
                var elements = multilist_content.getElementsByTagName('div');
                var current;
                var suffix = "pid" + productID;
                var length = elements.length;
                for (var i = 0; i < length; i++) {
                    current = elements[i];
                    dojo.removeClass(current, 'mapmultilistview_active');
                    if (current.id.endsWith(suffix))
                        dojo.addClass(current, 'mapmultilistview_active');
                }
            }
        }
        return item;
    }

    this.hideCurrentItem = function() {
        var item = geodata.maptips.currentMapTipsWindow.hide();
        if (this.map.infoWindow.isShowing) this.map.infoWindow.hide();
    }

}
// MapTipsLayer
