var Apparent = new Object();
Apparent.listings = new Hash();
Apparent.icons = new Hash();
Apparent.search_url = "/search";
Apparent.star_url = "/manage?do=star&";
Apparent.unstar_url = "/manage?do=unstar&";
Apparent.look_url = "/manage?do=look&";
Apparent.hide_url = "/manage?do=hide&";
Apparent.request_id = 0;

Event.observe(window, 'load', function() {
    Event.observe('filter_button', 'click', function (event) {
        var changed = false;
        
        if (Apparent.min_bedrooms != $('min_bedrooms').value) {
            Apparent.min_bedrooms = $('min_bedrooms').value;
            changed = true;
        }
    
        if (Apparent.max_price != $('max_price').value) {
            Apparent.max_price = $('max_price').value;
            changed = true;
        }
    
        if (changed == true) {
            search(Apparent.center);
        }
    })
});

function grid() {

    new Ajax.Request("/grid",
    {
        method: 'get',
        onSuccess: function (transport) {
            var points = eval(transport.responseText);
            points.each(function(point) {
                var marker = (new GMarker(new GLatLng(point[0],point[1])));
                Apparent.map.addOverlay(marker);
            
            });
        },
        onFailure: function (transport) {
            alert('Could not contact server. :(');
        }
    });
}


function search(point) {
    var url = Apparent.search_url + "?lat=" + point[0] + "&lon=" + point[1];

    var min_bedrooms = parseFloat($('min_bedrooms').value);
    if (!isNaN(min_bedrooms)) {
        url += "&bdrms=" + min_bedrooms;
    }

    var max_price = parseFloat($('max_price').value);
    if (!isNaN(max_price)) {
        url += "&price=" + max_price;
    }

    // keep track of the request number, so that
    // we know when to halt invalidated searches
    Apparent.request_id++;

    Apparent.center = point;
    removeAllListings();
    search_with_offset(url, 0, Apparent.request_id);
}

function search_with_offset(url, offset, request_id) {

    // a new request has occured, so stop here
    if (Apparent.request_id != request_id) {
        return;
    }

    var offset_url = url + "&offset=" + offset;

    new Ajax.Request(offset_url,
    {
        method: 'get',
        onSuccess: function (transport) {
            var new_listings = eval(transport.responseText);

            // a new request has occured, so stop here
            if (Apparent.request_id != request_id) {
                return;
            }

            // end of result set
            if (new_listings == null) {
                return;
            }

            new_listings.each(function (data) {
                var listing = makeListing(data);
                Apparent.listings.set(data.key, listing);
                Apparent.map.addOverlay(listing.marker);
                updateMarker(listing.marker, listing.info);
            });

            search_with_offset(url, offset + 40, request_id);    

        },
        onFailure: function (transport) {
            alert('Could not contact server. :(');
         }
    
    });

}

function removeAllListings() {
    Apparent.listings.values().each(function(listing) {
        Apparent.map.removeOverlay(listing.marker);
    });
    Apparent.listings = new Hash();
}

function createMap(center) {
    Apparent.map = new GMap2(document.getElementById("map"));
    Apparent.map.addControl(new GLargeMapControl());
    Apparent.map.addControl(new RecenterControl());

    Apparent.map.setCenter(new GLatLng(center[0], center[1]), 14);
    Apparent.map.enableScrollWheelZoom();

}

function initializeIcons() {
    var baseIcon = (new GMarker(new GLatLng(33.74718,-84.375))).getIcon();
    for (var i = 1; i <= 5; i++) {
            var new_icon = new GIcon(baseIcon);
            var seen_icon = new GIcon(baseIcon);
            var starred_icon = new GIcon(baseIcon);

            new_icon.image = "/images/new0" + i + ".png"
            seen_icon.image = "/images/seen0" + i + ".png"
            starred_icon.image = "/images/starred0" + i + ".png"

            starred_icon.iconSize = new GSize(26, 37);
            starred_icon.iconAnchor = new GPoint(13, 36);

            Apparent.icons.set(i.toString(), new_icon);
            Apparent.icons.set(i.toString() + "seen", seen_icon);
            Apparent.icons.set(i.toString() + "star", starred_icon);
    }

}
function getIcon(data) { 
    var key = Math.min(data.bedrooms, 5).toString();
    if (data.star == true || data.star == "True") {
         key += "star";
    } else if (data.seen == true || data.seen == "True") {
         key += "seen";
    }
    return Apparent.icons.get(key);
}

function setMode(newMode) {
    if (newMode == Mode.centering) {
        Mode.current = newMode;
        Apparent.map.getDragObject().setDraggableCursor("crosshair");

        GEvent.addListener(Apparent.map, "click", 
            function(marker, point) {
                if (marker != null) return;

                 var new_center = [point.lat(), point.lng()];
                 setMode(Mode.viewing);
                 set_map_circle(new_center, distance);
                 search(new_center);
        });

    } else if (newMode == Mode.viewing) {
        Mode.current = newMode;

        Apparent.map.getDragObject().setDraggableCursor(GDraggableObject.getDraggableCursor());
        GEvent.clearListeners(Apparent.map, "click");
    }

}

function makeInfo(data) {
    
    var to_ret = '<div class="listing">';

    to_ret += '<div class="star_container">';
    if (data.star || data.star == "True")
        to_ret += '<img class="listing_star" border="0" src="images/star_active.png" onclick="Apparent.unstar(\'' + data.key + '\');"/>';
    else
        to_ret += '<img class="listing_unstar" border="0" src="images/star_inactive.png" onclick="Apparent.star(\'' + data.key + '\');"/>';
    to_ret += '</div>';

    to_ret += '<div class="listing_header" onclick="Apparent.open(\'' + data.key + '\');">';
    to_ret += data.description;
    to_ret += '<img class="listing_open" border="0" src="images/open.png"/>';
    to_ret += '</div>';

    to_ret += '<div class="listing_body">';
    to_ret += '$' + data.cost + ' &mdash; ' + data.bedrooms + ' bedrooms' + ' &mdash; ';

    if (data.days_ago == 0)
        to_ret += "posted today! &mdash;";
    else
        to_ret += "posted " + data.days_ago + " days ago &mdash; ";

    to_ret += '<span class="hide_link" onclick="Apparent.hide(\'' + data.key + '\');">';
    to_ret += 'Hide';
    to_ret += '</span>';  
    to_ret += '</div>';

    to_ret += '</div>';

    return to_ret;
}


function makeListing(data) {
    var location = new GLatLng(data.latitude, data.longitude);
    return {
        "location" : location,
        "bedrooms" : data.bedrooms,
        "saved"    : data.saved,
        "marker"   : new GMarker(location, getIcon(data)), 
        "url"      : data.url,
        "info"     : makeInfo(data),
        "seen"     : data.seen,
        "star"     : data.star
    };
}

Apparent.star = function(key) {
    var url = Apparent.star_url + "key="  + key;
    stateChange(url, true);
}
Apparent.unstar = function(key) {
    var url = Apparent.unstar_url + "key=" + key;
    stateChange(url, true);
}

Apparent.hide = function(key) {
    var listing = Apparent.listings.get(key);
    Apparent.map.removeOverlay(listing.marker);
    Apparent.listings.unset(key);
 
    var url = Apparent.hide_url + "key=" + key;
    stateChange(url, false);
}

Apparent.open = function(key) {
    var listing = Apparent.listings.get(key);
    window.open(listing.url);
    self.focus();

    if (!listing.seen || listing.seen == "False") {
        Apparent.map.removeOverlay(listing.marker);
        var icon = getIcon({'bedrooms':listing.bedrooms,
                            'seen': true,
                            'star': listing.star});
        listing.marker = new GMarker(listing.location, icon)

        Apparent.map.addOverlay(listing.marker);
        updateMarker(listing.marker, listing.info);
        listing.marker.openInfoWindowHtml(listing.info);

        var url = Apparent.look_url + "key=" + key;
        stateChange(url, false);
    }
}

function stateChange(url, update) {
    new Ajax.Request(url,
    {
        method: 'get',
        onSuccess: function (transport) {

            if (!update) // don't process updated data
                return;

            var updated = eval(transport.responseText);
            updated.each(function (data) {
                var global_listing = Apparent.listings.get(data.key);
                if (global_listing != 'undefined') {
                    Apparent.map.removeOverlay(global_listing.marker);
                }
                
                var listing = makeListing(data);
                Apparent.listings.set(data.key, listing);
                Apparent.map.addOverlay(listing.marker);
                updateMarker(listing.marker, listing.info);

                if (updated.length == 1) {
                    listing.marker.openInfoWindowHtml(listing.info);
                }

            });
        },
        onFailure: function (transport) {
            alert('Could not contact server. :(');
         }
    
    });
}

function updateMarker(marker, content) {
    GEvent.addListener(marker, "click", function() {
        marker.openInfoWindowHtml(content);
    });
}


/*
 * circle generation stuff
 */
function set_map_circle(center, distance) {
    if (circle != null) { Apparent.map.removeOverlay(circle); }

    var points = generate_circle(center, distance);
    circle = new GPolyline(points, "#00ff00", 7, 0.5);
    Apparent.map.addOverlay(circle);   
}

function generate_circle(center, distance) {
    var points = float_range(0, Math.PI * 2, Math.PI / 16);
    var lat_long_points = new Array();

    points.each(function(point) {
        var lat = center[0] + ((distance * Math.sin(point))/68.70);
        var lon = center[1] + ((distance * Math.cos(point))/53.06);
        lat_long_points.push(new GLatLng(lat, lon));
    });
    lat_long_points.push(lat_long_points[0]);
    return lat_long_points;
}
function float_range(low, high, inc) {
    var values = new Array();
    while (low <= high) {
        values.push(low);
        low += inc;
    }
    return values;
}

function RecenterControl() { }
RecenterControl.prototype = new GControl();
RecenterControl.prototype.initialize = function(map) {
  var container = document.createElement("div");

  var zoomInDiv = document.createElement("div");
  this.setButtonStyle_(container);
  container.appendChild(document.createTextNode("Move the circle"));
  GEvent.addDomListener(container, "click", function() {
    setMode(Mode.centering);
  });

  map.getContainer().appendChild(container);
  return container;
}
RecenterControl.prototype.getDefaultPosition = function() {
  return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(80, 15));
}
RecenterControl.prototype.setButtonStyle_ = function(button) {
  button.style.textDecoration = "underline";
  button.style.color = "#0000cc";
  button.style.backgroundColor = "white";
  button.style.font = "small Arial";
  button.style.border = "1px solid black";
  button.style.padding = "2px";
  button.style.marginBottom = "3px";
  button.style.textAlign = "center";
  button.style.width = "6em";
  button.style.cursor = "pointer";
}
