/***
 * place.js - Posts and comments functions
 * Ariel Barmat
 */

/*** Place Wiki ***/

function getWiki() {
    return $(".wiki-edit textarea");
}
function toggleWiki() {
    $(".wiki").toggle();
    $(".wiki-edit").toggle();
    getWiki().focus(); 
}

function updateWiki(place_id) {
    msg = getWiki().val();
    currentMsg = $("#description-full").text();

    toggleWiki();
    
    if(currentMsg == msg) return;

    
    $.post(
        url = '/a/places/' + place_id + '/wiki',
        {'m': msg}, 
        function(data) {
            location.reload(true);
        }
    );
}

function updateTags(obj, url) {
    tags = $("#popup-tag #tags").val();
    currentTags = $("#popup-tag #tags_current").val();

    obj.parent.tb_remove();

    //avoid unnecessary post
    if(currentTags == tags) return;
    
    $.ajax({
        type:'POST', 
        url: url, 
        data: {'tags': tags},
        success: function(data) {
            location.reload(true);
        },
        error: function(xhr, txtStatus, errorThrown) {
            alert('error ' + xhr.status + ' -- ' + xhr.statusText);
        },            
        complete: function(xhr, txtStatus) {}
    });
}

/*** Locator Functions ***/

function locateme() {
    locationStart();

    if(hasGoogleGears())
        return gearsLocate();
    else if(hasGeolocation())
        return navLocate();
    else
        locationError('Could not find locator service');
}

function hasGoogleGears() { return window.google && google.gears; }
function hasGeolocation() { return navigator.geolocation; }
function hasLocator() { return hasGeolocation() || hasGoogleGears() }

/*** Gears Location ***/

function gearsGet(msg) {
    window.open("http://gears.google.com/?action=install&message=" + msg + "&return=http://www.weegoh.com/home");
}

function gearsLocate() {
    try {
        var geolocation = google.gears.factory.create('beta.geolocation');

        geolocation.getCurrentPosition(gearsSuccess, gearsError, {
            enableHighAccuracy: true,
            gearsRequestAddress: true
        });
    }
    catch(e) {
        locationError('Error using Geolocation API: ' + e.message);
    }
}
function gearsSuccess(p) {
    locationSuccess(
        p.coords.latitude,
        p.coords.longitude, 
        gearsAddressStr(p.gearsAddress)
    );
}
function gearsError(err) {
    locationError('Error retrieving your location: ' + err.message); 
}

function gearsAddressStr(addr) {
    var s = '';
    
    if(addr.streetNumber) s += addr.streetNumber + ' ';
    if(addr.street)       s += addr.street       + ', ';
    if(addr.city)         s += addr.city         + ', ';
    if(addr.region)       s += addr.region       + ', ';
    if(addr.country)      s += addr.country
    
    return s;
}

/*** W3C Geolocation API  ***/

function navLocate() {
    try {
        navigator.geolocation.getCurrentPosition(navSuccess, navError, {
            enableHighAccuracy: true
        });
    }
    catch(e) {
        locationError('Error using Geolocation API: ' + e.message);
    }
}

function navSuccess(p) {
    locationSuccess(
        p.coords.latitude, 
        p.coords.longitude, 
        null
    );
}

function navError(err) {
    locationError('Error retrieving your location: ' + err.message);
}

/*** Locator Getters ***/

function getLocator() {
    return $("#locator");
} 
function getLocatorPrg(loc) {
    return loc.find("#locator-working");
}
function getLocatorRes(loc) {
    return loc.find("#locator-results");
}
function getLocatorItems(loc) {
    return loc.find("#locator-items");
}

/*** Location Handlers ***/

function locationStart() {
    loc = getLocator();
    getLocatorPrg(loc).show();
    getLocatorRes(loc).hide();
}

function locationSuccess(lat, lon, addr) {
    $.ajax({
        type:'POST', 
        url: '/a/locate', 
        data: {
            'c': lat.toFixed(6) + ',' + lon.toFixed(6),
            'r': (addr == null)? 1 : 0
        },
        success: function(data) {
            d = JSON.parse(data);

            if(d['error_msg']) 
                return locationError(d['error_msg']);
            
            var html = '';
            
            for(i = 0; i < d['objects'].length; i++) {
                var item = d['objects'][i];
                
                if(addr != null)
                    item['display_name'] = (i == 0) ? addr : item['display_name'];
            
                html += renderLocationItem(item);
            }

            loc = getLocator();
            getLocatorItems(loc).html(html);
            getLocatorRes(loc).show();
        },
        error: function(xhr, txtStatus, errorThrown) {
            locationError(txtStatus);
        },
        complete: function(xhr, txtStatus) {
            locationComplete();
        }
    });
}

function locationComplete() {
    loc = getLocator();
    getLocatorPrg(loc).hide();
}

function locationError(msg) {
    alert(msg);
    locationComplete();
}

function renderLocationItem(item) {    
    var html = '';
    html = '<li>';
    html += '<span class="actions">';
    html += '<a href="' + item['link'] + '/go">[checkin]</a>';
    html += '</span>';                
    html += '<a href="' + item['link'] + '">' + item['display_name'] + '</a>';
    html += '</li>';
    
    return html;
}

/*** Weegoh Geocoder ***/

function GoogleGeoResponse() {

    this.parseLatLng = function(ll) {
        var obj = new Object;
        obj.lat = ll.lat();
        obj.lng = ll.lng();
    
        return obj;
    }
    
    this.parseLatLngBounds = function(llb) {
        var obj = new Object;
        obj.southwest = this.parseLatLng(llb.getSouthWest());
        obj.northeast = this.parseLatLng(llb.getNorthEast());
        
        return obj;
    }

    this.parseGeometry = function(geo) {
        var obj = new Object;
        obj.location = this.parseLatLng(geo.location);
        obj.viewport = this.parseLatLngBounds(geo.viewport);

        if (geo.bounds)
            obj.bounds = this.parseLatLngBounds(geo.bounds);
        
        return obj;
    }

    this.parseDict = function(results) {
        nresults = results.length;
        objects = new Array(nresults);
        
        for(i = 0; i < nresults; i++) {
            result = results[i];
        
            var obj = new Object;
            obj.types = result.types;
            obj.formatted_address = result.formatted_address
            obj.geometry = this.parseGeometry(result.geometry)
                    
            objects[i] = obj;
        }
        return objects;    
    }

    this.parse = function(results) {
        return JSON.stringify(this.parseDict(results));    
    }    
}

/*** Geocode and display result address on screen ***/

function WeegohGeoNamer() {

    function handleError(status) { alert(status); }
    
    function handleFinished(results) {
        var response = new GoogleGeoResponse();

        $.ajax({
            type:'POST', 
            url: '/a/places/name', 
            data: {
                'q': response.parse(results),
                'c': $('.geoname').attr('id')
            },
            success: function(data) {
                d = JSON.parse(data);

                if(d['error_msg']) 
                    return handleError(d['error_msg']);

                var html = "@" + d['object']['display_name'];
                $('.geoname').html(html);
            },
            error: function(xhr, txtStatus, errorThrown) {
                handleError(txtStatus);        
            },            
            complete: function(xhr, txtStatus) {}
        });
    }

    this.handleResponse = function(results, status) {
        return (status == google.maps.GeocoderStatus.OK) ? handleFinished(results) : handleError(status);
    }
}

/*** Weegoh Base Geocoder ***/

function WeegohGeocoder() {

    this.geocoder = new google.maps.Geocoder();
    this.coord_re = new RegExp("^([-+]?(\\d+)\\.?(\\d+)?),([-+]?(\\d+)+\\.?(\\d+)?)$"); 
    this.geoworkers = Array();

    this.isCoord = function(coord) {
        return coord.match(this.coord_re);
    }

    this.geocodeCoord = function(worker, coord) {
        if(!this.isCoord(coord))
            return;
            
        var coord = coord.split(',');
        this.geocode(worker, coord[0], coord[1]);        
    }

    this.geocode = function(worker, lat, lng) {
        if (!this.geocoder) {
            alert('No valid geocoder available');
            return;
        }
        this.add(worker);

        this.geocoder.geocode({
            'latLng': new google.maps.LatLng(lat, lng)
        }, worker.handleResponse);
    }
    
    this.add = function(request) {
        this.geoworkers.push(request);
    }
    this.find = function(obj) {
        return this.geoworkers.indexOf(obj);
    }
    this.del = function(obj) {
        return this.geoworkers.splice(this.find(obj), 1);
    }
}
