var map = null;
var startup_points = null;
var current_trip = null;
var lines = null;
var labels = null;
// Required for plotting custom polylines
var dashed = [];
var origin_line = null;
var return_line = null;

function init(type, latitude, longitude, zoom) {
    if(GBrowserIsCompatible()) {
        map = new GMap2(document.getElementById('map_canvas'));
        
        switch(type) {
            case 'mini':
                map.addControl(new GSmallMapControl());
                break;
            case 'full':
                map.addControl(new GSmallMapControl());
                map.addControl(new GMapTypeControl());
                map.addControl(new GScaleControl());
                break;
        }
        
        map.enableScrollWheelZoom();
        
        map.setCenter(new GLatLng(latitude, longitude), zoom);
        
        var icon = new GIcon(G_DEFAULT_ICON);
        
        if((latitude == default_latitude) && (longitude == default_longitude)) {
            icon.image = http_host + '/images/icons/home-large.png';
            icon.shadow = http_host + '/images/icons/shadow-home-large.png';
        } else {
            icon.image = http_host + '/images/icons/us-flag.png';
            icon.shadow = http_host + '/images/icons/shadow-us-flag.png';
        }
        
        switch(type) {
            case 'mini':
                if((latitude == default_latitude) && (longitude == default_longitude)) {
                    icon.iconAnchor = new GPoint(12, 12);
                } else {
                    icon.iconAnchor = new GPoint(0, 24);
                }
                icon.iconSize = new GSize(24, 24);
                icon.shadowSize = new GSize(36, 24);
                break;
            case 'full':
                if((latitude == default_latitude) && (longitude == default_longitude)) {
                    icon.iconAnchor = new GPoint(16, 16);
                } else {
                    icon.iconAnchor = new GPoint(0, 32);
                }
                icon.iconSize = new GSize(28, 30);
                icon.shadowSize = new GSize(48, 32);;
                break;
        }
        
        var ll = new GLatLng(default_latitude, default_longitude);
        
        var marker = new GMarker(ll, {
            clickable : true,
            icon      : icon
        });
        
        switch(type) {
            case 'mini':
                GEvent.addListener(marker, 'click', redirect);
                break;
            case 'full':
                GEvent.addListener(marker, 'click', home);
                break;
        }
        
        map.addOverlay(marker);
        
        if(document.getElementById('json').value != '[]') {
            startup_points = YAHOO.lang.JSON.parse(
                document.getElementById('json').value
            );
            
            for(var i = 0; i < startup_points.length; i++) {
                var ll = new GLatLng(
                    startup_points[i].latitude,
                    startup_points[i].longitude
                );
                
                var icon = new GIcon(G_DEFAULT_ICON);
                switch(type) {
                    case 'mini':
                        icon.iconAnchor = new GPoint(12, 24);
                        icon.iconSize = new GSize(22, 22);
                        icon.shadowSize = new GSize(36, 24);
                        break;
                    case 'full':
                        icon.iconAnchor = new GPoint(16, 32);
                        icon.iconSize = new GSize(32, 32);
                        icon.shadowSize = new GSize(48, 32);
                        break;
                }
                
                switch(startup_points[i].type) {
                    case 'past':
                        icon.image = http_host + '/images/icons/default_icon.png';
                        //icon.shadow = http_host + '/images/icons/shadow-trip.png';
                        icon.iconSize = new GSize(16, 26);
                        icon.shadowSize = new GSize(30, 24)
                        break;
                    case 'current':
                        icon.image = http_host + '/images/icons/home-large.png';
                        icon.shadow = http_host + '/images/icons/shadow-home-large.png';
                        break;
                    case 'future':
                        icon.image = http_host + '/images/icons/future_icon.png';
                        //icon.shadow = http_host + '/images/icons/shadow-trip.png';
                        icon.iconSize = new GSize(16, 26);
                        icon.shadowSize = new GSize(30, 24)
                        break;
                }
               
                var marker = new GMarker(ll, {
                    clickable : true,
                    icon      : icon
                });
                
                ll.trip_id = startup_points[i].id;
                marker.trip_id = startup_points[i].id;
                
                switch(type) {
                    case 'mini':
                        GEvent.addListener(marker, 'click', redirect);
                        break;
                    case 'full':
                        GEvent.addListener(marker, 'click', show_trip);
                        break;
                }
                
                startup_points[i].marker = marker;
                
                map.addOverlay(marker);
            }
        }
        
        if(type == 'full') {
            if(find_arg_value('trip_id')) {
                show_trip(find_arg_value('trip_id'));
            } else {
                for(var i = 0; i < startup_points.length; i++) {
                    if(startup_points[i].type == 'current') {
                        show_trip(startup_points[i].id);
                        break;
                    }
                }
            }
        }
        
        lines = new Array();
        
        lines.push(new GGeoXml(
            http_host + '/kml/SSIB_Rank3-black-50.kml',
            manage_zoom
        ));
        lines.push(new GGeoXml(
            http_host + '/kml/SSIB_Rank7-yellow.kml',
            manage_zoom
        ));
        
        map.addOverlay(lines[0]);
        map.addOverlay(lines[1]);
        
        labels = new Object();
        GEvent.addListener(map, 'zoomend', manage_zoom);
    }
}

function marker_order(marker, b) {
    if(typeof marker.importance != 'undefined') {
        return GOverlay.getZIndex(marker.getPoint().lat()) + marker.importance * 10000000000;
    } else {
        return GOverlay.getZIndex(marker.getPoint().lat())
    }
}

function manage_zoom(arg) {
    if(map.getZoom() >= 4) {
        for(var i = 0; i < lines.length; i++) {
            if(lines[i].isHidden()) {
                lines[i].show();
            }
        }
    } else {
        for(var i = 0; i < lines.length; i++) {
            if(!lines[i].isHidden()) {
                lines[i].hide();
            }
        }
    }
    
    if(typeof labels.burma == 'object') {
        map.removeOverlay(labels.burma);
        labels.burma = undefined;
    }
    
    if(typeof labels.rangoon == 'object') {
        map.removeOverlay(labels.rangoon);
        labels.rangoon = undefined;
    }
    
    switch(map.getZoom()) {
        case 3:
            labels.burma = new GGroundOverlay(
                http_host + '/images/labels/burma/burma3.png',
                new GLatLngBounds(
                    new GLatLng(19.675694, 92.8125),
                    new GLatLng(22.9503, 100.195312)
            ));
            map.addOverlay(labels.burma);
            break;
        case 4:
            labels.burma = new GGroundOverlay(
                http_host + '/images/labels/burma/burma4.png',
                new GLatLngBounds(
                    new GLatLng(20.237459, 94.13085900000002),
                    new GLatLng(22.04084, 98.70117199999999)
            ));
            map.addOverlay(labels.burma);
            labels.rangoon = new GGroundOverlay(
                http_host + '/images/labels/rangoon/rangoon4.png',
                new GLatLngBounds(
                    new GLatLng(15.464269, 94.48242199999999),
                    new GLatLng(17.654491, 97.82226599999998)
            ));
            map.addOverlay(labels.rangoon);
            break;
        case 5:
            labels.burma = new GGroundOverlay(
                http_host + '/images/labels/burma/burma5.png',
                new GLatLngBounds(
                    new GLatLng(20.682129, 95.36132800000001),
                    new GLatLng(21.70643, 97.77831999999999)
            ));
            map.addOverlay(labels.burma);
            labels.rangoon = new GGroundOverlay(
                http_host + '/images/labels/rangoon/rangoon5.png',
                new GLatLngBounds(
                    new GLatLng(16.594082, 95.19104),
                    new GLatLng(17.722527, 97.229004)
            ));
            map.addOverlay(labels.rangoon);
            break;
        case 6:
            labels.burma = new GGroundOverlay(
                http_host + '/images/labels/burma/burma6.png',
                new GLatLngBounds(
                    new GLatLng(20.924501, 95.8),
                    new GLatLng(21.416252, 97.14111299999999)
            ));
            map.addOverlay(labels.burma);
            labels.rangoon = new GGroundOverlay(
                http_host + '/images/labels/rangoon/rangoon6.png',
                new GLatLngBounds(
                    new GLatLng(16.662506, 95.644226),
                    new GLatLng(17.306067, 96.70166)
            ));
            map.addOverlay(labels.rangoon);
            break;
        case 7:
            labels.burma = new GGroundOverlay(
                http_host + '/images/labels/burma/burma7.png',
                new GLatLngBounds(
                    new GLatLng(21.035288, 96.16332999999999),
                    new GLatLng(21.342594, 96.888428)
            ));
            map.addOverlay(labels.burma);
            labels.rangoon = new GGroundOverlay(
                http_host + '/images/labels/rangoon/rangoon7.png',
                new GLatLngBounds(
                    new GLatLng(16.791393, 95.877686),
                    new GLatLng(17.090918, 96.41601599999998)
            ));
            map.addOverlay(labels.rangoon);
            break;
        case 8:
            labels.rangoon = new GGroundOverlay(
                http_host + '/images/labels/rangoon/rangoon8.png',
                new GLatLngBounds(
                    new GLatLng(16.751289, 96.003342),
                    new GLatLng(16.905743, 96.28006000000001)
            ));
            map.addOverlay(labels.rangoon);
            break;
        case 9:
            labels.rangoon = new GGroundOverlay(
                http_host + '/images/labels/rangoon/rangoon9.png',
                new GLatLngBounds(
                    new GLatLng(16.833132, 96.067886),
                    new GLatLng(16.886032, 96.21276899999998)
            ));
            map.addOverlay(labels.rangoon);
            break;
        case 10:
            labels.rangoon = new GGroundOverlay(
                http_host + '/images/labels/rangoon/rangoon10.png',
                new GLatLngBounds(
                    new GLatLng(16.85022, 96.10050200000001),
                    new GLatLng(16.88209, 96.178436)
            ));
            map.addOverlay(labels.rangoon);
            break;
        case 11:
            labels.rangoon = new GGroundOverlay(
                http_host + '/images/labels/rangoon/rangoon11.png',
                new GLatLngBounds(
                    new GLatLng(16.857695, 96.11784400000002),
                    new GLatLng(16.875929, 96.164017)
            ));
            map.addOverlay(labels.rangoon);
            break;
        case 12:
            labels.rangoon = new GGroundOverlay(
                http_host + '/images/labels/rangoon/rangoon12.png',
                new GLatLngBounds(
                    new GLatLng(16.863321, 96.131355),
                    new GLatLng(16.871822, 96.15226)
            ));
            map.addOverlay(labels.rangoon);
            break;
        case 13:
            labels.rangoon = new GGroundOverlay(
                http_host + '/images/labels/rangoon/rangoon13.png',
                new GLatLngBounds(
                    new GLatLng(16.864985, 96.13602399999999),
                    new GLatLng(16.869255, 96.14719400000001)
            ));
            map.addOverlay(labels.rangoon);
            break;
        case 14:
            labels.rangoon = new GGroundOverlay(
                http_host + '/images/labels/rangoon/rangoon14.png',
                new GLatLngBounds(
                    new GLatLng(16.865828, 96.138824),
                    new GLatLng(16.868086, 96.144623)
            ));
            map.addOverlay(labels.rangoon);
            break;
        case 15:
            labels.rangoon = new GGroundOverlay(
                http_host + '/images/labels/rangoon/rangoon15.png',
                new GLatLngBounds(
                    new GLatLng(16.86673, 96.14048),
                    new GLatLng(16.867931, 96.143372)
            ));
            map.addOverlay(labels.rangoon);
            break;
    }
}

function get_startup_point_by_trip_id(trip_id) {
    for(var i = 0; i < startup_points.length; i++) {
        if(startup_points[i].id == trip_id) {
            return startup_points[i];
        }
    }
    
    return false;
}

function home(ll) {
    map.openInfoWindow(ll, 'The Secretary\'s primary office is located at the U.S. Department of State headquarters in Washington, DC.');
}

function redirect(ll) {
    if(typeof ll.trip_id != 'undefined') {
        if(window.parent) {
            window.parent.location = redirect_link + '?trip_id=' + ll.trip_id;
        } else {
            window.location = redirect_link + '?trip_id=' + ll.trip_id;
        }
    } else {
        if(window.parent) {
            window.parent.location = redirect_link;
        } else {
            window.location = redirect_link;
        }
    }
}

function show_trip(arg) {
    if(typeof arg == 'object') {
        var trip_id = arg.trip_id;
    } else {
        var trip_id = arg;
    }
    
    if(!isNaN(trip_id)) {
        http_process.send(
            http_host + '/lookup/stops/',
            'trip_id=' + trip_id,
            'plot_trip'
        );
    }
    
    return false;
}

function plot_trip(result) {
    try {
        result = YAHOO.lang.JSON.parse(result);
        // Hide elements from previously clicked marker
        if(current_trip) {
            for(var i = 0; i < current_trip.stops.length; i++) {
                map.removeOverlay(current_trip.stops[i].marker);
            }
            if(current_trip.line) {
                map.removeOverlay(current_trip.line);
            }
            // Remove dashed line since it has multiple overlay instances
            if(dashed) {
                for(var j=0; j < dashed.length; j++) {
                    if((j % 2) == 0) {
                        map.removeOverlay(dashed[j]);
                    }
                }           
            }
            // Remove plotted origin and return trip polylines
            if(origin_line) {
                map.removeOverlay(origin_line);
            }
            if(return_line) {
                map.removeOverlay(return_line);
            }
            get_startup_point_by_trip_id(current_trip.trip.id).marker.show();
        }
        
        map.panTo(new GLatLng(result.trip.latitude, result.trip.longitude));
        get_startup_point_by_trip_id(result.trip.id).marker.hide();
        var now = new Date();
        // Array for past trip stop coordinates
        var lls = new Array();
        // Array for current trip stops coordinates
        var curr_x = new Array();
        var curr_y = new Array();    
        
      
        for(var i = 0; i < result.stops.length; i++) {
            var arrive = parse_date(result.stops[i].arrive);
            var depart = parse_date(result.stops[i].depart);    
            
            switch(result.trip.type) {
                case 'past':
                    var icon = new GIcon(G_DEFAULT_ICON);
                    icon.image = http_host + '/images/icons/past-stop-' + (i + 1) + '.png';
                    icon.iconAnchor = new GPoint(3, 32);
                    icon.iconSize = new GSize(32, 32);
                    icon.shadow = http_host + '/images/icons/shadow-stop.png';
                    icon.shadowSize = new GSize(48, 32);
                    break;
                case 'current':
                    var icon = new GIcon(G_DEFAULT_ICON);
                    icon.iconSize = new GSize(32, 32);
                    icon.shadowSize = new GSize(48, 32);
                    
                    if(arrive.getTime() <= now.getTime() && depart.getTime() >= now.getTime()) {
                        icon.image = http_host + '/images/icons/home-large.png';
                        icon.iconAnchor = new GPoint(16, 16);
                        icon.shadow = http_host + '/images/icons/shadow-home-large.png';
                    } else if(arrive.getTime() >= now.getTime()) {
                        icon.image = http_host + '/images/icons/future-stop-' + (i + 1) + '.png';
                        icon.iconAnchor = new GPoint(3, 32);
                        icon.shadow = http_host + '/images/icons/shadow-stop.png';
                    } else if(depart.getTime() <= now.getTime()) {
                        icon.image = http_host + '/images/icons/past-stop-' + (i + 1) + '.png';
                        icon.iconAnchor = new GPoint(3, 32);
                        icon.shadow = http_host + '/images/icons/shadow-stop.png';
                    }
                    break;
                case 'future':
                    var icon = new GIcon(G_DEFAULT_ICON);
                    icon.image = http_host + '/images/icons/future-stop-' + (i + 1) + '.png';
                    icon.iconAnchor = new GPoint(3, 32);
                    icon.iconSize = new GSize(32, 32);
                    icon.shadow = http_host + '/images/icons/shadow-stop.png';
                    icon.shadowSize = new GSize(48, 32);
                    break;
            }
            
            var ll = new GLatLng(
                result.stops[i].latitude,
                result.stops[i].longitude
            );
            
            // Use coordinates from past trips
            if(arrive.getTime() <= now.getTime()) {
                lls.push(ll);
            } 
            // Use coordinates from present trip
            if(arrive.getTime() <= now.getTime()) {      
                curr_x.push(ll.lat());
                curr_y.push(ll.lng());
            }
            
            var marker = new GMarker(ll, {
                clickable     : true,
                icon          : icon,
                zIndexProcess : marker_order
            });
            
            if(result.trip.type == 'current') {
                if(arrive.getTime() <= now.getTime() && depart.getTime() >= now.getTime()) {
                    marker.importance = 1;
                } else {
                    marker.importance = 0;
                }
            }
            
            GEvent.addListener(marker, 'click', show_stop);
            
            ll.trip_id = result.trip.id;
            marker.trip_id = result.trip.id;
            
            ll.stop_id = result.stops[i].id;
            marker.stop_id = result.stops[i].id;
            
            result.stops[i].marker = marker;
            
            map.addOverlay(marker);
            
        }
        // Plot line from origin to first trip stop   
        origin_line = new GPolyline([
            new GLatLng(default_latitude, default_longitude),
            new GLatLng(result.stops[0].latitude, result.stops[0].longitude)
            ], '#0033FF', 2, 0.6); 
        map.addOverlay(origin_line);
        
        // Plot line if there are multiple coordinates on a trip
        if(lls.length && result.trip.type==='past') {
            result.line = new GPolyline(lls, '#0033FF', 2, 0.6);            
            map.addOverlay(result.line);
            // Plot return to origin line
            return_line = new GPolyline([
                new GLatLng(default_latitude, default_longitude),
                new GLatLng(result.stops[(result.stops.length-1)].latitude, result.stops[(result.stops.length-1)].longitude)
                    ], '#0033FF', 2, 0.6);
            map.addOverlay(return_line);
            
        } else if (lls.length && result.trip.type==='current') {
            // Remove coordinate of current stop
            lls.pop();
            result.line = new GPolyline(lls, '#0033FF', 2, 0.6);
            map.addOverlay(result.line);
            // Plot dashed line only for the current stop to previous stop
            curr_x.reverse();
            curr_y.reverse();     
            dashed_line(curr_x, curr_y);
        } else {
            result.line = null;
        }
       
        current_trip = result;
    } catch(e) {
    }
}
// Plots the dashed line by passing two coordinate arrays
function dashed_line(set_x, set_y) {

    var coor_x = set_x;
    var coor_y = set_y;

    // Calculate length
    var len_a = (coor_x[1] - coor_x[0]);
    var len_b = (coor_y[1] - coor_y[0]);

    var len_c = Math.sqrt( (len_b * len_b) + (len_a * len_a) );
    var a_theta = Math.acos(Math.abs(len_a) / len_c);
    var b_theta = Math.asin(Math.abs(len_b) / len_c);

    if(len_a < 0) { a_theta += Math.PI; }
    if(len_b < 0) { b_theta += Math.PI; }

    var num_steps = 25;
    var step_length = len_c / num_steps;

    var move_x = (Math.cos(a_theta)) * step_length;
    var move_y = (Math.sin(b_theta)) * step_length;
    
    for( var i = 0; i < num_steps; i++) {

        var end_x = move_x + coor_x[0];
        var end_y = move_y + coor_y[0];
        
        // Plot the gaps in the line
        if((i % 2) == 0) {
            // Starting point
            dashed[i] = new GPolyline([
  		        new GLatLng(coor_x[0], coor_y[0]),
  		        new GLatLng(end_x, end_y)
  		        ], '#0033FF', 3, 0.6); 
  		        map.addOverlay(dashed[i]);      
        }
        coor_x[0] = end_x;
        coor_y[0] = end_y;
    } 
}
 
function show_stop(ll) {
    var html = new Array();
    html.push('<iframe src="' + http_host + '/stop/?stop_id=' + ll.stop_id + '" style="border: none; margin: 0px; padding: 0px; height: 400px; width: 500px" height="500" width="600" frameborder="0" marginheight="0" marginwidth="0"></iframe>');
    
    map.openInfoWindowHtml(ll, html.join(''));
}
