

var crimeTracker = {};


crimeTracker.dom = {
	map: "map",
	message: "message",
	locationForm: "crimesearchform",
	locationInput: "#address",
	city: "#city",
	info: "#crimeinfo",
	dateSelector: "crimedt",
	crimeSelector: "crimeselector",
	crimeSwitchClassName: "active"
};


crimeTracker.events =
{
    init: function() {
        GEvent.addListener(crimeTracker.map, "load", crimeTracker.display.message.hide);
        GEvent.addListener(crimeTracker.map, "dblclick", function(overlay, point) { crimeTracker.track.fromPoint(point, crimeTracker.settings.searchArea.zoom); });

        YAHOO.util.Event.addListener(crimeTracker.dom.locationForm, "submit", function(e) {
            crimeTracker.track.fromLocation(e);
            pageTracker._trackPageview("/interactive/crime-tracker/search/" + $(crimeTracker.dom.city).val());
        });

        YAHOO.util.Event.addListener(crimeTracker.dom.dateSelector, "change", function(e) {
            crimeTracker.track.fromChange();
            pageTracker._trackPageview("/interactive/crime-tracker/date/" + $('#' + crimeTracker.dom.dateSelector).val());
        });

        crimeTracker.data.loading.subscribe(crimeTracker.display.message.show);
        crimeTracker.data.ready.subscribe(crimeTracker.display.init);

        var crimeSwiches = document.getElementById(crimeTracker.dom.crimeSelector).getElementsByTagName("a");
        for (var i = 0; i < crimeSwiches.length; i++) {
            YAHOO.util.Event.addListener(crimeSwiches[i], "click", function(e) {
                crimeTracker.types.change(this);
                pageTracker._trackPageview("/interactive/crime-tracker/crimeswitch");
            });
        }

        $('#reset a').click(crimeTracker.reset);

        $('#address').focus(function() { $('#crimesearch').addClass('typing'); });
        $('#address').blur(function() { if ($('#address').val() == '') $('#crimesearch').removeClass('typing'); });
        if ($('#address').val() != '') $('#crimesearch').addClass('typing');

        $('#source').click(function() { $('#disclaimer').toggle('500'); });
        $('#disclaimer').click(function() { $('#disclaimer').hide('500'); });

        pageTracker._trackPageview("/interactive/crime-tracker/pv");
    }
};


crimeTracker.display = {
    init: function() {
        for (var i = 0; i < crimeTracker.crimes.length; i++) crimeTracker.display.crimeMarker(crimeTracker.crimes[i]);
        crimeTracker.display.message.hide();
    },

    crimeMarker: function(crime) {
        if (crime.crimetype == 'warning') {
            var point = new GLatLng(parseFloat(crime.lat) + 0.0002 * crime.dup, parseFloat(crime.lng) + 0.0002 * crime.dup);
            var warningIcon = crimeTracker.display.crimeIcon(crime.crimetype);
            var warningMarker = new GMarker(point, { icon: warningIcon });
            var warningInfo = '<span style="font-family:arial;">We apologize that the data you selected is currently unavailable.<br>Crime data is posted as soon as possible after<br>it is received from the local law enforcement agency.</span>';
            GEvent.addListener(warningMarker, "mouseover", function() { warningMarker.openInfoWindowHtml(warningInfo); });
            crimeTracker.map.addOverlay(warningMarker);
        } else {
            var point = new GLatLng(parseFloat(crime.lat) + 0.0002 * crime.dup, parseFloat(crime.lng) + 0.0002 * crime.dup);
            var crimeIcon = crimeTracker.display.crimeIcon(crime.crimetype);
            var crimeMarker = new GMarker(point, { icon: crimeIcon });
            var crimeInfo = crime.description1 + "<br />" + crime.description2 + "<br />" + crime.crimedate + " " + crime.crimetime + "<br />" + crime.address.substr(0, crime.address.indexOf(' ')) + " BLOCK OF " + crime.address.substr(crime.address.indexOf(' ') + 1);
            GEvent.addListener(crimeMarker, "mouseover", function() { crimeMarker.openInfoWindowHtml(crimeInfo.toUpperCase()); });
            crimeTracker.map.addOverlay(crimeMarker);
        }
    },

    crimeIcon: function(crimeType) {
        if (crimeType == 'warning') {
            var warningIcon = new GIcon(G_DEFAULT_ICON);
            warningIcon.image = '/crimetracker/_icons/warning.png';
            warningIcon.iconSize = new GSize(64, 64);
            warningIcon.iconAnchor = new GPoint(32, 64);
            warningIcon.infoWindowAnchor = new GPoint(32, 0);
            warningIcon.shadow = null;
            return warningIcon;
        } else {
            var crimeIcon = new GIcon(G_DEFAULT_ICON);
            crimeIcon.image = crimeTracker.settings.icons.image(crimeType);
            crimeIcon.iconSize = crimeTracker.settings.icons.size;
            crimeIcon.iconAnchor = crimeTracker.settings.icons.anchorPoint;
            crimeIcon.shadow = null;
            return crimeIcon;
        }
    },

    area: function(point) {
        var settings = crimeTracker.settings.searchArea;
        var polyline = new GPolyline(
			[new GLatLng(point.lat() - settings.offset.y, point.lng() - settings.offset.x),
			new GLatLng(point.lat() - settings.offset.y, point.lng() + settings.offset.x),
			new GLatLng(point.lat() + settings.offset.y, point.lng() + settings.offset.x),
			new GLatLng(point.lat() + settings.offset.y, point.lng() - settings.offset.x),
			new GLatLng(point.lat() - settings.offset.y, point.lng() - settings.offset.x)],
			settings.color, settings.thickness);
        crimeTracker.map.addOverlay(polyline);
    },

    message: {
        show: function() { $(crimeTracker.dom.message).show(); },
        hide: function() { $(crimeTracker.dom.message).hide(); }
    }
};


crimeTracker.track = {
    fromPoint: function(point, zoom) {
        crimeTracker.map.clearOverlays();
        crimeTracker.map.setCenter(point, zoom);
        crimeTracker.display.area(point);
        crimeTracker.data.request(point);
    },

    fromLocation: function(e) {
        YAHOO.util.Event.stopEvent(e);
        var locationSearch = $(crimeTracker.dom.locationInput).val() + " " + $(crimeTracker.dom.city).val();
        var geocoder = new GClientGeocoder();
        geocoder.getLatLng(locationSearch, function(point) {
            if (point) {
                crimeTracker.track.fromPoint(point, crimeTracker.settings.searchArea.zoom);
                //crimeTracker.checkCity();
            }
            else {
                alert("Address not found");
            }
        });
    },

    fromChange: function() {
        crimeTracker.track.fromPoint(crimeTracker.map.getCenter());
    }
};


crimeTracker.data = {
    request: function(point) {
        crimeTracker.data.loading.fire();
        var requestUrl = crimeTracker.settings.dataUrl;
        requestUrl += "?lat=" + point.lat() + "&lng=" + point.lng();
        requestUrl += "&xoffset=" + crimeTracker.settings.searchArea.offset.x + "&yoffset=" + crimeTracker.settings.searchArea.offset.y;
        requestUrl += "&types=" + crimeTracker.types.active;
        requestUrl += "&month=" + crimeTracker.date.getSelectedMonth() + "&year=" + crimeTracker.date.getSelectedYear();
        var request = YAHOO.util.Connect.asyncRequest('GET', requestUrl, { success: crimeTracker.data.fill, failure: crimeTracker.data.failure });
    },

    fill: function(o) {
        crimeTracker.crimes = YAHOO.lang.JSON.parse(o.responseText);
        crimeTracker.data.ready.fire();
    },

    failure: function(o) {
        alert("Error");
    },

    loading: new YAHOO.util.CustomEvent("dataLoading"),
    ready: new YAHOO.util.CustomEvent("dataReady")
};


crimeTracker.types =
{
    active: [],

    init: function() {
        crimeTracker.types.active = crimeTracker.settings.activeTypes;
        for (var j = 0; j < crimeTracker.types.active.length; j++) YAHOO.util.Dom.get(crimeTracker.types.active[j]).className = crimeTracker.dom.crimeSwitchClassName;
    },

    change: function(crimeSwitch) {
        if (crimeSwitch.className == "") {
            crimeSwitch.className = crimeTracker.dom.crimeSwitchClassName;
            crimeTracker.types.active.push(crimeSwitch.id);
        }
        else {
            crimeSwitch.className = "";
            crimeTracker.types.active.splice(crimeTracker.types.active.indexOf(crimeSwitch.id), 1);
        }
        crimeTracker.track.fromChange();
    }
};

crimeTracker.date = {
    getSelectedMonth: function() {
        var dateSelector = YAHOO.util.Dom.get(crimeTracker.dom.dateSelector);
        var selectedMonth = dateSelector[dateSelector.selectedIndex].value;
        return selectedMonth.substr(0, 2);
    },

    getSelectedYear: function() {
        var dateSelector = YAHOO.util.Dom.get(crimeTracker.dom.dateSelector);
        var selectedYear = dateSelector[dateSelector.selectedIndex].value;
        return selectedYear.substr(2, 4);
    }
};

crimeTracker.reset = function() {
    crimeTracker.settings.map.defaults(crimeTracker.map);
    crimeTracker.types.init();
    crimeTracker.track.fromPoint(new GLatLng(crimeTracker.settings.map.lat, crimeTracker.settings.map.lng));
}


crimeTracker.init = function() {
    crimeTracker.map = new GMap2(document.getElementById(crimeTracker.dom.map));
    crimeTracker.settings.map.defaults(crimeTracker.map);
    crimeTracker.events.init();
    crimeTracker.types.init();
    crimeTracker.track.fromPoint(new GLatLng(crimeTracker.settings.map.lat, crimeTracker.settings.map.lng));
}

crimeTracker.checkCity = function() {
    if ($('#' + crimeTracker.dom.dateSelector).val() == '042009')
        switch ($(crimeTracker.dom.city).val()) {
        case 'Bethany, OK':
        case 'Norman, OK':
            crimeTracker.showMissingDataAlert();
            break;
    }
}

crimeTracker.showMissingDataAlert = function() {
    alert('The crime data you have requested is currently unavailable but will be updated when it is received.');
}

if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(elt /*, from*/) {
        var len = this.length;

        var from = Number(arguments[1]) || 0;
        from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
        if (from < 0)
            from += len;

        for (; from < len; from++) {
            if (from in this &&
          this[from] === elt)
                return from;
        }
        return -1;
    };
}



