// JavaScript Document
//<![CDATA[

var entries;

var map = null;
var mashupEvent = null;
var contribs = null;
var zones = null;

var zonePrevSel = new Object();
var highlightQueue = new Array();

var photoVisible = false;

// Icons
var baseIcon = new GIcon();

// define the base icon for entry markers
baseIcon.shadow = "../images/markers/entry-marker-shadow.png";
baseIcon.iconSize = new GSize(36, 48);
baseIcon.shadowSize = new GSize(70, 48);
baseIcon.iconAnchor = new GPoint(18, 48);
baseIcon.infoWindowAnchor = new GPoint(18, 2);
//baseIcon.infoShadowAnchor = new GPoint(18, 25);
//baseIcon.dragCrossAnchor = new GPoint(-1, 9);

/*
 * Utility functions.
 */
function resizeApp() {
    var mapElem = document.getElementById("main-div");
    var height = getWindowHeight();
    
    if (height >= 0) {
        mapElem.style.height = height + "px";
    }
}

function getWindowHeight() {
    if (window.self && self.innerHeight) {
        return self.innerHeight;
    }
    if (document.documentElement && document.documentElement.clientHeight) {
        return document.documentElement.clientHeight;
    }
    return 0;
}

/*
 * Load GMaps. Application entry point.
 */
function loadApp(me, mc, mz) {
    
    mashupEvent = me;
    contribs = mc;
    zones = mz;
    
    if (GBrowserIsCompatible()) {
        
        // Create map instance
        map = new GMap2(document.getElementById("main-div"));
        map.setCenter(new GLatLng(0,0));
        map.setMapType(G_SATELLITE_TYPE);
        map.enableDoubleClickZoom()
        map.enableScrollWheelZoom();
        
        // Controls
        map.addControl(new GLargeMapControl());
        map.addControl(new GMapTypeControl());
        map.addControl(new GScaleControl());
        
        // Initialize zones
        initZones();
        
        // Resize and tell GMaps API
        resizeApp();
        map.checkResize();
        
        mashupEvent.bounds = new GLatLngBounds(
        new GLatLng(mashupEvent.eventBoundBottom, mashupEvent.eventBoundLeft),
        new GLatLng(mashupEvent.eventBoundTop, mashupEvent.eventBoundRight));
        var zoom = map.getBoundsZoomLevel(mashupEvent.bounds);
        map.setCenter(mashupEvent.bounds.getCenter(), zoom);
        map.savePosition();
        
        var len = zones.length;
        for(var key in zones) {
            zonePrevSel[key] = zones[key].active = false;
        }
        redrawZones();
    }
}

function updateCallback(data, responseCode) {
    
    if(responseCode == 200) {
        
        entries = eval('(' + data + ')');
        for(var key in entries) {
            lat = entries[key].lat;
            lng = entries[key].lng;
            var point = new GLatLng(parseFloat(lat), parseFloat(lng));
            eventId = entries[key].eventId;
            entryId = entries[key].entryId;
            
            var marker = createEntryMarker(point, eventId, entries[key]);
            map.addOverlay(marker);
        }
    }
    else
        alert("Could not access data [" + responseCode + "]");
}

/*
 * Update map according to control options.
 */
function updateMap() {
    
        /*
         * Prepare request...
         * 1. Get contributor IDs
         * 2. Get zones IDs
         * 3. Parse date/times
         * 4. Process request
         */
    
    // Clear ALL overlays
    map.clearOverlays();
    
    // Contributor IDs
    var cntArr = new Array();
    var cntStr = "";
    if(document.getElementById("cntAll").selected) {
        cntStr = "0";
    }
    else {
        for(var key in contribs) {
            var contribOption = document.getElementById(key);
            if(contribOption.selected)
                cntArr.push(contribs[key].contributorId);
        }
        cntStr = cntArr.join(',');
    }
    
    // Zone IDs
    var zonArr = new Array();
    var zonStr = "";
    
    var allZones = null;
    if(document.getElementById("zonAll").selected)
        var allZones = true;
    else
        var allZones = false;
    
    for(var key in zones) {
        var zone = zones[key];
        var zoneOption = document.getElementById(key);
        if(zoneOption.selected || allZones) {
            zonArr.push(zones[key].zoneId);
            zone.active = true;
        }
        else {
            zone.active = false;
        }
        zonStr = zonArr.join(',');
    }
    
    redrawZones();
    
    // Timestamps
    var fromTimestamp = Date.parse(document.getElementById("fromDate").value);
    if(isNaN(fromTimestamp))
        fromTimestamp = 0;
    else
        fromTimestamp /= 1000;
    
    var toTimestamp = Date.parse(document.getElementById("toDate").value);
    if(isNaN(toTimestamp))
        toTimestamp = 0;
    else
        toTimestamp /= 1000;
    var urlRequest = "?eventId=" + mashupEvent.eventId + "&contributorIds=" + cntStr + "&zoneIds=" + zonStr + "&startTimestamp=" + fromTimestamp + "&endTimestamp=" + toTimestamp + "&tags=0";
    
    GDownloadUrl("../app/get-json.php" + urlRequest, updateCallback);
}

// creates a mashup entry marker
function createEntryMarker(point, eventId, entry) {
	var entryId = entry.entryId;
    var icon = new GIcon(baseIcon);
	var mkrPath = "../photos/event" + eventId + "/mkr/mkr-" + entry.photoId + ".png";
    icon.image = mkrPath;
    var marker = new GMarker(point, {"icon":icon,"title":entries["ent"+entryId].text});
    
    // add onclick listener
    GEvent.addListener(marker, "click", function () {
        openMarker(marker, entry);
    });
    
    return marker;
}

// Open up the marker to view thumbnail
function openMarker(marker, entry) {
    var dt = new Date(entry.createDT*1000);
    var dtStr = dt.toLocaleString();
	var photoId = entry.photoId;
	
    var photoBase = "../photos/event" + entry.eventId;
	var photoPath = photoBase + "/photo-" + photoId + entry.photoExt;
	var thumbPath = photoBase + "/tmb/tmb-" + photoId + ".jpg";

	entry.text = entry.text.replace(/'/g, "&apos;");
	entry.tags = entry.tags.replace(/'/g, "&apos;");

    $html = "<div style='width: 220px; text-align: center; font-size: large; color: #333;'>" +
    "<p><strong>" + entry.text + "</strong><br />" +
    "<span style='font-size: smaller; font-style: italic'>" + dtStr + "</span></p>" +
    "<a href='#' class='link' onclick='Lightbox.show(\"" + photoPath + "\", \"" + entry.text + "\");'><img src='" + thumbPath + "' class='link' alt='Photo' width='160' height='120' /></a><br />" +
	 "<span style='font-size: small; text-align: right'>(<a href='#' class='link' onclick='Lightbox.show(\"" + photoPath + "\", \"" + entry.text + "\");'>view full photo</a>)</span>" +
    "<p>Tags: " + entry.tags + "</p></div>";
    marker.openInfoWindowHtml($html);

}

// Pop zone overlay off
function highlightPop() {
    var poly = highlightQueue.pop();
    map.removeOverlay(poly);
}

function redrawZones() {
    for(var key in zones) {
        var zone = zones[key];
        
        // Active (selected)
        if(zone.active) {
            zone.poly = new GPolygon(zone.points, zone.color, 3, 0.75, zone.color, 0.0); 
        }
        // Inactive
        else {
            zone.poly = new GPolygon(zone.points, "#ffffff", 2, 0.8, "#ffffff", 0.0);
        }
        
        map.addOverlay(zone.poly);
    }
}

function zonesChange() {	
    for(var key in zones) {
        var zoneOption = document.getElementById(key);
        if(zoneOption.selected && !zonePrevSel[key]) {
            var poly = new GPolygon(zones[key].points, "#000000", 0.0, 0.0, zones[key].color, 0.5);
            map.addOverlay(poly);
            highlightQueue.unshift(poly); // queue up next poly
            setTimeout("highlightPop()", 1000);
        }
        zonePrevSel[key] = zoneOption.selected;
    }
}

function initZones() {
    var i = 0;
    for(var key in zones) {
        
        var zone = zones[key];
        
        var rgbCol = hsv2Rgb((i*59)%255, 1.0, 0.95);
        zone.color = rgb2Color(rgbCol[0], rgbCol[1], rgbCol[2]);
        
        zone.points = getCircle(
        new GLatLng(zone.zoneLat, zone.zoneLng),
        zone.zoneRad/1000,
		15);
        i++;
    }
}

function getCircle(center, radius, nodes) {
    // Calculating km/degree
    var latConv = center.distanceFrom(new GLatLng(center.lat()+0.1, center.lng()))/100;
    var lngConv = center.distanceFrom(new GLatLng(center.lat(), center.lng()+0.1))/100;
    
    var points = [];
    var step = parseInt(360/nodes)||10;
    for(var i=0; i<=360; i+=step){
        var pint = new GLatLng(
        center.lat() + (radius/latConv * Math.cos(i * Math.PI/180)),
        center.lng() + (radius/lngConv * Math.sin(i * Math.PI/180)));
        points.push(pint);
    }
    return points;
}

/** Utility Functions **/
// rand - Generates random number from 1 to n, inclusive
function rand( n ) {
    return ( Math.floor( Math.random( ) * n + 1 ) );
}

// byte2hex - Takes number n from 0-255 and converts to hexadecimal string e.g. 'AA'
// Courtesy Jim Bumgardner of krazydad.com
function byte2Hex(n) {
    var nybHexString = "0123456789ABCDEF";
    return String(nybHexString.substr((n >> 4) & 0x0F,1)) + nybHexString.substr(n & 0x0F,1);
}

// RGB2Color - Takes 3 hexadecimal string color components and concatenates into standard HTML format
// Courtesy Jim Bumgardner of krazydad.com
function rgb2Color(r, g, b) {
    return '#' + byte2Hex(r) + byte2Hex(g) + byte2Hex(b);
}

function hsv2Rgb(h, s, v) {
    
    if(s == 0) {
        // achromatic (grey)
        r = g = b = v;
        return;
    }
    
    h /= 60;			// sector 0 to 5
    i = Math.floor(h);
    f = h - i;		// factorial part of h
    p = v * (1 - s);
    q = v * (1 - s * f);
    t = v * (1 - s * (1 - f));
    switch(i) {
        case 0:
            r = v; g = t; b = p;
            break;
        case 1:
            r = q; g = v; b = p;
            break;
        case 2:
            r = p; g = v; b = t;
            break;
        case 3:
            r = p; g = q; b = v;
            break;
        case 4:
            r = t; g = p; b = v;
            break;
        default: // case 5:
            r = v; g = p; b = q;
            break;
    }
    r = Math.floor(r * 255);
    g = Math.floor(g * 255);
    b = Math.floor(b * 255);
    
    return new Array(r, g, b);
}

//]]>