/*
    Coded By Steven Bower (cc) 2008-2010
    TurnWheel Designs http://turnwheel.com/
    BPWebDesign http://bpwebdesign.com/
*/


// Variables
var color_def_poly = '#7E7DED';
var color_def_rect = '#000000';
var color_def_marker = 'red';
var weight_def = 4;
var opacity_def = 0.7;
var poly_color_use = color_def_poly;
var city = city || 'windsor';
// Map Vars
var xmlfile = '';
var map = null;
var geocoder = null;
var proc_data = null;
var proc_rcode = null;
var route_active = 0;
var routes = []; // Array of routes
var hide_routes = hide_routes || false;
var hide_route_b = hide_route_b || false;
var defaultDay = defaultDay || 'monday';
var twocolors = false;

var createMarker = function(point,info,color) {
    var icon = new GIcon();
    icon.image = '/images/marker_'+color+'.png';
    icon.shadow = '/images/marker_shadow.png';
    icon.iconSize = new GSize(12,20);
    icon.shadowSize = new GSize(22,20);
    icon.iconAnchor = new GPoint(6,20);
    icon.infoWindowAnchor = new GPoint(5,1);

    var marker = new GMarker(point,icon);
    GEvent.addListener(marker, 'click', function() {
        marker.openInfoWindowHtml(info);
    });
    return marker;
};

// RouteControl Object
var RouteControl = function() {};
RouteControl.prototype = new GControl();

// Creates a one DIV for each of the buttons and places them in a container
// DIV which is returned as our control element. We add the control to
// to the map container and return the element for the map class to
// position properly.
RouteControl.prototype.initialize = function(map) {
    var container = document.createElement("div");
    
    function setActive(route) {
        for (var i = 0; i < routes.length; ++i) {
            if (route == i) routes[i].style.fontWeight = "bold";
            else routes[i].style.fontWeight = "normal";
        }
    }

    routes[0] = document.createElement("div");
    this.setButtonStyle_(routes[0],1);
    container.appendChild(routes[0]);
    routes[0].appendChild(document.createTextNode("Route A"));
    GEvent.addDomListener(routes[0],"click",function() {
        poly_color_use = color_def_poly;
        map.clearOverlays();
        procxml(proc_data,proc_rcode);
        
        if (route_active !== 0) setActive(0);
        route_active = 0;
    });
    
    if (!hide_route_b) {
        routes[1] = document.createElement("div");
        this.setButtonStyle_(routes[1],0);
        container.appendChild(routes[1]);
        routes[1].appendChild(document.createTextNode("Route B"));
        GEvent.addDomListener(routes[1],"click",function() {
            poly_color_use = '#EB404F';
            map.clearOverlays();
            procxml(proc_data,proc_rcode);
            
            if (hide_route_b) {
                alert("There is no route B");
            }
            if (route_active !== 1) setActive(1);
            
            route_active = 1;
        });
    }

    map.getContainer().appendChild(container);
    return container;
};

// Positioning
RouteControl.prototype.getDefaultPosition = function() {
    return new GControlPosition(G_ANCHOR_BOTTOM_RIGHT,new GSize(7,30));
};

// Sets the proper CSS for the given button element.
RouteControl.prototype.setButtonStyle_ = function(button,bold) {
    button.style.textDecoration = "none";
    button.style.a = "color:#000;";
    button.style.backgroundColor = "#FFF";
    button.style.font = "1em Arial,sans-serif";
    button.style.border = "1px solid black";
    button.style.padding = "1px";
    button.style.marginBottom = "1px";
    button.style.textAlign = "center";
    button.style.width = "5.3em";
    button.style.cursor = "pointer";
    
    if (bold == 1) button.style.fontWeight = "bold";
};

// OnLoad Function
var load = function() {
    if (GBrowserIsCompatible()) {
        map = new GMap2(document.getElementById('map'));
        geocoder = new GClientGeocoder();
        
        map.addControl(new GLargeMapControl());
        map.addControl(new GMapTypeControl());
        if (!hide_routes) map.addControl(new RouteControl());
        //map.setCenter(new GLatLng(center[0],center[1]),14);
        
        // Reset local vars
        poly_color_use = color_def_poly;
        route_active = 0;
        
        // Download the data and load it on the map
        var file = xmlfile || 'data.xml';
        GDownloadUrl('/xml/'+file,procxml);
    }
};

// Process XML Code
var procxml = function(data,rcode) {
    var xml = GXml.parse(data);
    proc_data = data;
    proc_rcode = rcode;
    
    // Set center
    // Required Tags: lat,lng
    // Optional Tags: zoom
    var center = xml.documentElement.getElementsByTagName('center');
    if (center.length > 0) {
        var point = new GLatLng(parseFloat(center[0].getAttribute('lat')),
                        parseFloat(center[0].getAttribute('lng')));
        var zoom = parseInt(center[0].getAttribute('zoom')) || 14;
        map.setCenter(point,zoom);
    }

    // Create Markers (<marker>)
    // Required Tags: lat,lng
    // Optional Tags: info,color
    var markers = xml.documentElement.getElementsByTagName('marker');
    var prevcolor = '';
    for (var i = 0; i < markers.length; i++) {
        var point = new GLatLng(parseFloat(markers[i].getAttribute('lat')),
                        parseFloat(markers[i].getAttribute('lng')));
        var info = markers[i].getAttribute('info');
        var color = markers[i].getAttribute('color') || color_def_marker;
        var marker = createMarker(point,info.replace(/\\n/g,'<br />'),color);
        
        if (prevcolor !== '' && prevcolor != color) twocolors = true;
        
        map.addOverlay(marker);
        prevcolor = color;
    }
    
    if (twocolors) hide_route_b = true;

    // Create Lines <line>
    // Required Tags: coords (orderd by lng,lat,0) Designed to work with data exported from Google Earth
    // Optional Tags: color,weight,opacity
    var lines = xml.documentElement.getElementsByTagName("line");
    for (var i = 0; i < lines.length; i++) {
        var points = [];
        var color = lines[i].getAttribute("color") || color_def_poly;
        var coords = lines[i].getAttribute("coords").split(" ");
        var weight = lines[i].getAttribute("weight") || weight_def;
        var opacity = lines[i].getAttribute("opacity") || opacity_def;
        
        if (color != poly_color_use) continue;
        
        for (var x = 0; x < coords.length; x++) {
            var y = coords[x].split(",");
            if (y.length > 3 || y.length < 2) continue; // Not even. Needs to be an even number of values to create 2 pairs
            points.push(new GLatLng(parseFloat(y[1]),parseFloat(y[0])));
        }
        
        map.addOverlay(new GPolyline(points,color,parseInt(weight),parseFloat(opacity)));
    }

    // Create Rectangles <rect>
    // Required Tags: coords
    // Optional Tags: color,weight,opacity
    var rects = xml.documentElement.getElementsByTagName("rect");
    for (var i = 0; i < rects.length; i++) {
        var lats = rects[i].getAttribute("lat").split(",");
        var lngs = rects[i].getAttribute("lng").split(",");
        var color = rects[i].getAttribute("color") || color_def_rect;
        var weight = rects[i].getAttribute("weight") || weight_def;
        var opacity = rects[i].getAttribute("opacity") || opacity_def;
        
        if (lats.length < 2 || lngs.length < 2) continue;
        
        var rect = new GLatLngBounds(
            new GLatLng(lats[0],lngs[0]),
            new GLatLng(lats[1],lngs[1]));
            
        var info = rects[i].getAttribute("info") || null;
        var nrect = new Rectangle(rect,color,parseInt(weight),parseFloat(opacity));
            
        map.addOverlay(nrect);
    }
};

// A Rectangle is a simple overlay that outlines a lat/lng bounds on the
// map. It has a border of the given weight and color and can optionally
// have a semi-transparent background color.
var Rectangle = function(bounds,opt_color,opt_weight,opt_opacity) {
    this.bounds_ = bounds;
    this.weight_ = opt_weight || 2;
    this.color_ = opt_color || '#888888';
    this.opacity_ = opt_opacity || 0.45;
};

// Create overlay
Rectangle.prototype = new GOverlay();

// Creates the DIV representing this rectangle.
Rectangle.prototype.initialize = function(map) {
    // Create the DIV representing our rectangle
    var div = document.createElement('div');
    div.style.border = this.weight_ + 'px solid ' + this.color_;
    div.style.position = 'absolute';

    // Our rectangle is flat against the map, so we add our selves to the
    // MAP_PANE pane, which is at the same z-index as the map itself (i.e.,
    // below the marker shadows)
    map.getPane(G_MAP_MAP_PANE).appendChild(div);

    this.map_ = map;
    this.div_ = div;
};

// Remove the main DIV from the map pane
Rectangle.prototype.remove = function() {
    this.div_.parentNode.removeChild(this.div_);
};

// Copy our data to a new Rectangle
Rectangle.prototype.copy = function() {
    return new Rectangle(this.bounds_, this.weight_, this.color_,
                       this.backgroundColor_, this.opacity_);
};

// Redraw the rectangle based on the current projection and zoom level
Rectangle.prototype.redraw = function(force) {
    // We only need to redraw if the coordinate system has changed
    if (!force) return;

    // Calculate the DIV coordinates of two opposite corners of our bounds to
    // get the size and position of our rectangle
    var c1 = this.map_.fromLatLngToDivPixel(this.bounds_.getSouthWest());
    var c2 = this.map_.fromLatLngToDivPixel(this.bounds_.getNorthEast());

    // Now position our DIV based on the DIV coordinates of our bounds
    this.div_.style.width = Math.abs(c2.x - c1.x) + 'px';
    this.div_.style.height = Math.abs(c2.y - c1.y) + 'px';
    this.div_.style.left = (Math.min(c2.x, c1.x) - this.weight_) + 'px';
    this.div_.style.top = (Math.min(c2.y, c1.y) - this.weight_) + 'px';
    this.div_.style.opacity = this.opacity_;
    this.div_.style.filter = 'alpha(opacity='+(this.opacity_*100)+')';
};

// Show address inputed by user form
/*var showAddress = function(address) {
    geocoder.getLatLng(address,
    function(point) {
        if (!point) alert(address + " not found");
        else {
            map.setCenter(point,14);
            var marker = createMarker(point,address,color_def_marker);
            map.addOverlay(marker);
        }
    });
};*/

var anchor = window.location.hash;
// Wait for document before binding events
$(function() {
    // Bind Event for Search
    /*$('button[rel="gmap"]').click(function() {
        // Show address based on input value
        showAddress($('#address').val());
        return false;
    });*/
    
    // See if we need to load a different XML file
    if (anchor.length > 2 && $('#routelist').find('a[href="'+anchor+'"]').length != 0) {
        xmlfile = city+'_'+anchor.replace(/#/,'')+'.xml';
        $('#routelist').find('a[href="'+anchor+'"]').addClass('bold');
    }
    else {
        xmlfile = city+'_'+defaultDay+'.xml'; // Monday is default (most popular day)
        $('#routelist').find('a[href="#'+defaultDay+'"]').addClass('bold');
    }
    
    load(); // Load Map
    
    // Bind unload function
    $('body').unload(GUnload);
    
    // Check for changes in anchor
    $('#routelist a').click(function() {
        var self = $(this);
        xmlfile = city+'_'+(self.attr('href').replace(/#/,''))+'.xml'; // Update XML
        
        // Update Bold Link Status
        self.siblings('.bold').removeClass('bold');
        self.addClass('bold');
        
        // Re-Load Map
        load();
        console.log(xmlfile);
    });
});