/*************************
 ADDRESS SEARCH FUNCTIONS
**************************/

/**
 * finds the submitted address and sends the request to search for it
 */
function getAddress(address) {
    // reset the places array
    places = null;
    var address = $('#'+address).val();
    if (address != "") {
        // store the address in the global variable so we can log it later
        search_address = address;
        // initialise the geocoder
        if (geocoder == null) {
            geocoder = new GClientGeocoder();
            geocoder.setBaseCountryCode('UK');
        }
        // format the post code to try and get more accurate results - 
        var coords = /^\-?[0-9]+\.[0-9]+,\s?\-?[0-9]+\.[0-9]+$/;
        if (!coords.test(address)) {
            var new_address = formatPostcode(address);
            new_address = new_address+", UK";
            // search for the address
            geocoder.getLocations(new_address, findAddress);
        }
        else {
            var lat = address.split(",")[0];
            var lng = address.split(",")[1];
            showAddress(lat, lng);
        }
    }
    else {
        alert("Please enter a post code or address first");
    }
    return false;
}

/**
 * Finds addresses from a given input
 */
function findAddress(response) {
    // variables for database logging
    var status_code = response.Status.code;
    var number_results = 0;
    
    var requested = response.name;
    if (!response || response.Status.code != 200) {
        alert("Sorry, the post code or address, "+requested+", could not be found");
    }
    else {
        number_results = response.Placemark.length;
        places = new Array();
        for (var i=0; i<response.Placemark.length; i++) {
            var place = response.Placemark[i];
            var place_address = place.address;
            var place_lat = place.Point.coordinates[1];
            var place_lng = place.Point.coordinates[0];
            
            var j = places.length;
            places[j] = new Array();
            places[j]['address'] = place_address;
            places[j]['lat'] = parseFloat(place_lat);
            places[j]['lng'] = parseFloat(place_lng);
        }
        if (places.length == 1) {
            showAddress(places[0]['lat'], places[0]['lng']);
        }
        else {
            showAddressPicker();
        }
    }
    // log the search in the database
    //logAddressSearch(status_code, number_results);
}

/**
 * Shows the address picker when more than one address is returned
 */
function showAddressPicker() {
    var picker = $('#picker');
    var london_places = new Array();
    var uk_places = new Array();
    
    var picker_content = "<div id='pick_address'><p>Your search returned "+places.length+" results. Please choose from the list below:</p>";
    for (var i=0; i<places.length; i++) {
        if (inLondon(new GLatLng(places[i]['lat'], places[i]['lng']))) {
            london_places[london_places.length] = places[i];
        }
        else {
            uk_places[uk_places.length] = places[i];
        }
    }
    // London results
    picker_content += "<p>Results in London</p>";
    if (london_places.length > 0) {
        for (var i=0; i<london_places.length; i++) {
            picker_content += "<div";
            if (i%2 == 0) picker_content += " class='stripe'";
            picker_content += "><a href='#' onclick='tb_remove(); showAddress("+london_places[i]['lat']+", "+london_places[i]['lng']+"); return false;'>"+london_places[i]['address']+"</a></div>"
        }
    }
    else {
        picker_content += "<div>There were no results from London</div>";
    }
    // Rest of the UK results
    if (uk_places.length > 0) {
        picker_content += "<p>Results from the rest of the UK</p>";
        for (var i=0; i<uk_places.length; i++) {
            picker_content += "<div";
            if (i%2 == 0) picker_content += " class='stripe'";
            picker_content += "><a href='#' onclick='tb_remove(); showAddress("+uk_places[i]['lat']+", "+uk_places[i]['lng']+"); return false;'>"+uk_places[i]['address']+"</a></div>"
        }
    }
    picker_content += "<div class='close'><input type='button' onclick='tb_remove(); return false;' value='close window' /></div></div>";
    picker.html(picker_content);
    
    var trigger = $('#picker_trigger');
    trigger.unbind("click");
    tb_init(trigger);    
    $('#picker_trigger').trigger('click');
}

/**
 * Adds a marker at a selected address and zooms in on it
 */
function showAddress(lat, lng) {
    if (search_marker != null) map.removeOverlay(search_marker);
    var point = new GLatLng(lat, lng);
    search_marker = new GMarker(point);
    GEvent.addListener(search_marker, "click", function() {
        if (confirm("Do you want to remove the address marker from the map?")) {
            map.removeOverlay(search_marker);
            search_marker = null;
        }
    });
    map.addOverlay(search_marker);
    map.setCenter(point, 16);
}

/**
 * Formats a postcode to add the space if it is not already there
 * and removes the last two letters as this gives more accurate results
 */
function formatPostcode(address) {
    // no spaces included
    if (address.indexOf(" ") < 0) {
        var postcodes = new Array();
        // FULL POSTCODE
        postcodes[0] = /^[A-Za-z]{1,2}[0-9]{1,2}[A-Za-z]?[0-9][A-Za-z]{2}$/;
        // LAST LETTER MISSING
        postcodes[1] = /^[A-Za-z]{1,2}[0-9]{1,2}[A-Za-z]?[0-9][A-Za-z]{1}$/;
        // LAST TWO LETTERS MISSING AND LETTER AT END OF FIRST PART
        postcodes[2] = /^[A-Za-z]{1,2}[0-9]{1,2}[A-Za-z][0-9]$/;
        for (var i=0; i<postcodes.length; i++) {
            if (postcodes[i].test(address)) {
                switch (i) {
                    case 0: address = address = address.substr(0, address.length-2); break;
                    case 1: address = address.substr(0, address.length-1); break;
                    case 2: address = address; break;
                }
                address = address.substr(0, address.length-1)+" "+address.substr(address.length-1, address.length);
                break;
            }
        }
    }
    // spaces included
    else {
        var postcodes = new Array();
        // FULL POSTCODE
        postcodes[0] = /^[A-Za-z]{1,2}[0-9]{1,2}[A-Za-z]? [0-9][A-Za-z]{2}$/;
        // LAST LETTER MISSING
        postcodes[1] = /^[A-Za-z]{1,2}[0-9]{1,2}[A-Za-z]? [0-9][A-Za-z]{1}$/;
        for (var i=0; i<postcodes.length; i++) {
            if (postcodes[i].test(address)) {
                if (i ==0) {
                    address = address = address.substr(0, address.length-2);
                }
                else {
                    address = address.substr(0, address.length-1);
                }
                address = address.substr(0, address.length-1)+address.substr(address.length-1, address.length);
                break;
            }
        }
    }
    return address;
}

/**
 * Calculates whether a point is in London or not
 */
function inLondon(point) {
    return london_bounds.containsLatLng(point);
}