//////
// Copyright (C) 2009: Fabián Ezequiel Gallina
// Contact list: lugro-mesh-dev@lugro.org.ar
// Version 0.1
//
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
//////

/**
 * @package    Nightwing
 * @subpackage WifiDog Extensions
 * @author     Fabián Ezequiel Gallina <galli.87@gmail.com>
 * @copyright  2009 Fabián Ezequiel Gallina
 * @version    Subversion $Id$
 * @link       http://nightwing.lugro-mesh.org.ar/
 */

/**
 * Constructor
 *
 * @params GMap map The GMap instance
 * @params Array latlngs Array with the points of the line
 * @params string line_color The color of the line
 * @params string head_color The color of the arrow's head
 * @params float weight weight Arrow's Line weight
 * @params float opacity The Arrow opacity
 * @params string tooltip The tooltip to display when the arrow is clicked
 * @params JSON options Polyline and Polygon options
 *
 * @return GArrow instance
 */
function GArrow(map, latlngs, line_end_offset)
{
    this.line_end_offset = line_end_offset || parseFloat(0.0002);
    this.map = map;
    this.latlngs = latlngs;
    this.line_color = "#888888";
    this.head_color = "#888888";
    this.weight = 1;
    this.opacity = 0.8;
    this.tooltip = false;
    this.lat_offset = parseFloat(+0.0001);
    this.lng_offset = parseFloat(+0.0001);
    this.polyline_options = null;
    this.head_options = null;
}

/**
 * Adds the tooltip to the arrow
 *
 * @return void
 */
GArrow.prototype.add_tooltip = function()
{
    var self = this
    if(this.tooltip) {
        GEvent.addListener(
            this.polyline, "click",
            function() { alert(self.tooltip) }
        );
    }
}

/**
 * Returns if the latitude difference of vertex is positive
 *
 * @return bool
 */
GArrow.prototype.is_lat_pos = function()
{
    var val = parseFloat(this.latlngs[0].lat() - this.latlngs[1].lat());
    return val > 0;
}

/**
 * Returns if the longitude difference of vertex is positive
 *
 * @return bool
 */
GArrow.prototype.is_lng_pos = function()
{
    var val = parseFloat(this.latlngs[0].lng() - this.latlngs[1].lng());
    return val > 0;
}

/**
 * Draws the arrow's head
 *
 * @return void
 */
GArrow.prototype.draw_head = function()
{
    var lat_offset = this.lat_offset;
    var lng_offset = this.lng_offset;

    var lat = this.latlngs[1].lat();
    var lng = this.latlngs[1].lng();

    if(!this.is_lat_pos()) {
        lat_offset = lat_offset * -1;
    }

    if(!this.is_lng_pos()) {
        lng_offset = lng_offset * -1;
    }

    var arrow = new GPolygon(
        [new GLatLng(lat, lng),
         new GLatLng(lat + lat_offset, lng),
         new GLatLng(lat, lng + lng_offset),
         new GLatLng(lat, lng)],
        this.head_color, this.weight, this.opacity,
        this.head_color, this.opacity, this.head_options);

    this.map.addOverlay(arrow);
}

/**
 * Readjust the last GLatLng object of this.latlngs to fit the offset
 * defined by the user
 *
 * @return void
 */
GArrow.prototype.readjust_latlngs = function()
{
    var start_lat = this.latlngs[0].lat();
    var start_lng = this.latlngs[0].lng();

    var end_lat = this.latlngs[1].lat();
    var end_lng = this.latlngs[1].lng();

    if(!this.is_lat_pos()) {
        end_lat -= this.line_end_offset;
    } else {
        end_lat += this.line_end_offset;
    }

    if(!this.is_lng_pos()) {
        end_lng -= this.line_end_offset;
    } else {
        end_lng += this.line_end_offset;
    }

    this.latlngs = [new GLatLng(start_lat, start_lng),
                    new GLatLng(end_lat, end_lng)];
}

/**
 * Draws the arrow
 *
 * @return void
 */
GArrow.prototype.draw = function()
{
    this.readjust_latlngs();
    this.polyline = new GPolyline(
        this.latlngs, this.line_color, this.weight, this.opacity,
        this.polyline_options
    );
    this.add_tooltip();
    this.map.addOverlay(this.polyline);
    this.draw_head();
}
