/**
 * WordPress I Am Here Widget Map Functionality
 *
 * @author Klaus Komenda <mail@klauskomenda.com>
 * @namespace YAHOO.CRUSH.WordPress.widgets
 * @class iamhere
 * @requires YAHOO.CRUSH.WordPress.widgets.iamhere.config
 */
YAHOO.namespace("CRUSH.WordPress.widgets");

YAHOO.CRUSH.WordPress.widgets.iamhere = function () {
    // location config pulled in from external
    var loc_config = YAHOO.CRUSH.WordPress.widgets.iamhere.config;
    
    // module specific config
    var mod_config = {
        panel: { 
            id: "iah-mapContainer",
            options: {
                width: "670px", 
                fixedcenter: true, 
                draggable: false, 
                zindex: 4,
                modal: true,
                visible: false,
                height: "460px",
                close: true
            },
            headerText: "My current Location: " + loc_config.currentLocation.string
        },
        map: {
            width: 630,
            height: 390,
            pinImgPath: "/wp-content/plugins/i-am-here/img/poi_marker.png",
            pinImgWidth: 20,
            pinImgHeight: 34,
            homeImgPath: "/wp-content/plugins/i-am-here/img/home_marker.png",
            homeImgWidth: 49,
            homeImgHeight: 52,
            smartWindowTextClass: "infotext"
        },
        geonames: {
            XhrUrl: "/wp-content/plugins/i-am-here/widget/findNearbyWikipedia.php?lat=" + loc_config.currentLocation.lat + "&lng=" + loc_config.currentLocation.lon + "&maxRows=10"
        },
        showButton: {
            elType: "button",
            text: "show map"
        }
    };
    
    var myPanel = false;
    var panelBdEl;
    var map;
    var points = [];
    var markers = [];
    var yPoints = [];
    
    /**
     * displays a SmartWindow when user clicks on a pin
     * @method onSmartWinEvent
     * @param {Event} e Event object passed in by Event Handler
     */
    var onSmartWinEvent = function (e) {
        var currPoint = points[e.thisObj.id];
        
        var markup = "<div class='iah-widget-sw-container'>";
        markup += "<h6>";
        
        if (currPoint.wikipediaUrl) {
            markup += "<a href='http://" + currPoint.wikipediaUrl + "'>" + currPoint.name + "</a>";
        } else {
            markup += "My current Location: " + currPoint.name;
        }
        markup += "</h6>";

        if (currPoint.thumbnailImg) {
            markup += "<img src='" + currPoint.thumbnailImg + "' />";
        }
        
        if (currPoint.text) {
            markup += "<p>" + currPoint.text.substr(0, 200) + "...";
            if (currPoint.wikipediaUrl) {
                markup += "<a href='http://" + currPoint.wikipediaUrl + "'>Continue</a>";
            }
            markup += "</p>";
        }

        markup += "</div>";
        markers[e.thisObj.id].openSmartWindow(markup);
    };
    
    /**
     * Places markers on the map and attaches Event Listeners
     * @method placeMarkers
     */
    var placeMarkers = function () {
        var markerImg;
        
        // loop through our POIs
        for (var i in points) {
            markerImg = new YImage();
            
            if (points[i].type === "home") {
                // if it is our current location, use "home" pin image
                markerImg.src = mod_config.map.homeImgPath;
                markerImg.size = new YSize(mod_config.map.homeImgWidth, mod_config.map.homeImgHeight);
                markerImg.offset = new YCoordPoint(-10, 20);
                markerImg.offsetSmartWindow = new YCoordPoint(20, 20);
            } else if (points[i].type === "wiki") {
                // if it is a wiki POI, use "wiki" pin image
                markerImg.src = mod_config.map.pinImgPath;
                markerImg.size = new YSize(mod_config.map.pinImgWidth, mod_config.map.pinImgHeight);
                markerImg.offset = new YCoordPoint(-3, 0);
                markerImg.offsetSmartWindow = new YCoordPoint(10, 0);
            }
            
            // store YGeoPoints to be able to zoom and center Map correctly
            yPoints[i] = new YGeoPoint(points[i].lat, points[i].lng);
            markers[i] = new YMarker(yPoints[i], markerImg, i);
            
            map.addOverlay(markers[i]);
            YEvent.Capture(markers[i], EventsList.MouseClick, onSmartWinEvent);
        }
    };
    
    /**
     * Handles XHR from geonames.org for retrieving Wikipedia articles for POIs
     * @method getNearbyWikipedia 
     * @param {Object} o XHR response object
     */
    var getNearbyWikipedia = function (o) {
        var r = eval("(" + o.responseText + ")");
        
        if (r.geonames) {
            var POIs = r.geonames;
            var len = POIs.length;
            
            for (var i = 0; i < len; i++) {
                points[i + 1] = {
                    name: POIs[i].title,
                    lat: POIs[i].lat,
                    lng: POIs[i].lng,
                    type: "wiki",
                    text: POIs[i].summary,
                    wikipediaUrl: POIs[i].wikipediaUrl,
                    thumbnailImg: POIs[i].thumbnailImg
                };
            }
        } else {
            if (typeof(YEH) != 'undefined') {
                var e = new Error([
                                "Different Ajax Response expected",
                                "YAHOO.CRUSH.WordPress.widgets.iamhere.getNearbyWikipedia"
                                ]);
                YEH.logRunTimeError(e);
            } 
        }
        
        placeMarkers();
        
        // set map (dimensions, zoom level) so that all pins are visible
        var bestZoom = map.getBestZoomAndCenter(yPoints).zoomLevel;
        var bestPoint = map.getBestZoomAndCenter(yPoints).YGeoPoint;
        map.drawZoomAndCenter(bestPoint, bestZoom);
    };
    
    /**
     * Failure Methode for Wikipedia Request
     * @method getNearbyWikipediaFail
     * @param {Object} o XHR response object
     */
    var getNearbyWikipediaFail = function (o) {
        console.log("Fail");
        var e = new Error([
                        "Ajax Request to Wikipedia failed",
                        "YAHOO.CRUSH.WordPress.widgets.iamhere.getNearbyWikipediaFail"
                        ]);
        if (typeof(YEH) != 'undefined') {
            YEH.logRunTimeError(e);
        }
        
    };
    
    /**
     * Renders Map
     * @method renderMap
     *
     * TODO: should be refactored cause it does not actually render the map but
     * does a couple of other things instead...
     */
    var renderMap = function () {
        panelBdEl = YAHOO.util.Dom.getElementsByClassName("bd", "div", mod_config.panel.id)[0];
        map = new YMap(panelBdEl, YAHOO_MAP_REG, new YSize(mod_config.map.width, mod_config.map.height));
        
        if (typeof(YEH) != 'undefined' && !map) {
            var e = new Error([
                            "Could not create Y!Map",
                            "YAHOO.CRUSH.WordPress.widgets.iamhere.renderMap"
                            ]);
            YEH.logRunTimeError(e);
        } 
        
        // Add map type control
        map.addTypeControl();

        // Add zoom control
        map.addZoomLong();

        // Add pan control
        map.addPanControl();
        
        points[0] = {
            name: loc_config.currentLocation.string,
            lat: loc_config.currentLocation.lat,
            lng: loc_config.currentLocation.lon,
            type: "home"
        };
        
        YAHOO.util.Connect.asyncRequest("GET", mod_config.geonames.XhrUrl, { success: getNearbyWikipedia, failure: getNearbyWikipediaFail });
        
        YAHOO.util.Dom.setStyle(panelBdEl, "display", "block");
    };
    
    /**
     * Handles closing of the Map Overlay
     * @method handlePanelClose
     */
    var handlePanelClose = function () {
        var closeEl = YAHOO.util.Dom.getElementsByClassName("container-close", "a", mod_config.panel.id)[0];
        YAHOO.util.Event.addListener(closeEl, "click", function () {
            YAHOO.util.Dom.setStyle(panelBdEl, "display", "none");
        });
    };
    
    var setUpMapPanel = function () {
        myPanel = new YAHOO.widget.Panel(mod_config.panel.id, mod_config.panel.options);
        
        myPanel.setHeader(mod_config.panel.headerText);
        myPanel.setBody("");
        myPanel.render(document.body);
        showPanel();
    }
    
    var showPanel = function () {
        renderMap();
        myPanel.show();
        handlePanelClose();
    }

    /**
     * Creates Overlay and initiates the map rendering
     * @method createPanel
     */
    var createPanel = function () {
        if (!myPanel) {
            // load maps js file dynamically
            //Begin by creating a new Loader instance:
            var loader = new YAHOO.util.YUILoader({
                onSuccess: setUpMapPanel
            });
            
            //Here we define the Yahoo! Maps API module 
            //in YUI Loader:
            loader.addModule({		
                name: 'yahoomaps', //module name; must be unique
                type: 'js', //can be "js" or "css"
                // a variable that will be available when the script is loaded.  Needed
                // in order to act on the script immediately in Safari 2.x and below:
                varName: "YahooMapsAPIAjax", 
                //can use a path instead, extending base path:
                fullpath: 'http://l.yimg.com/d/lib/map/js/api/ymapapi_3_8_2_3.js'
            });
            
            //This appid, available from 
            //http://developer.yahoo.com/maps/ajax/ , must come before 
            //the insert method is called.  And yes, this must be a global variable:
            YMAPPID = "tCIXFDbV34Fs2QOUXcY8bKnJ6xPylbWqRU.T2rXPA.Z9EaZqMtbA8ajLdWWOOLSCnd1cJg--";
        
            loader.require("yahoomaps"); //include the new  module
            loader.insert();
        } else {
            showPanel();
        }
    };
    
    /**
     * Creates the "Show Map" button in the markup
     * @method createShowMapButton 
     */
    var createShowMapButton = function () {
        var locListEl = YAHOO.util.Dom.getElementsByClassName('meta')[0];
        
        var mapButtonEl = document.createElement(mod_config.showButton.elType);
        var mapButtonSpan = document.createElement('span');
        mapButtonSpan.className = 'offscreen';
        var mapButtonText = document.createTextNode(mod_config.showButton.text);
        mapButtonSpan.appendChild(mapButtonText);
        mapButtonEl.appendChild(mapButtonSpan);
        
        YAHOO.util.Event.addListener(mapButtonEl, "click", createPanel);
        YAHOO.util.Event.addListener(mapButtonEl, "mouseover", function (e) {
            YAHOO.util.Dom.setStyle(this, "cursor", "pointer");
        });
        
        locListEl.appendChild(mapButtonEl);
    };

    // initiate the module when location widget is displayed in the sidebar
    if (document.getElementById("location")) {
        createShowMapButton();
    }
}();


