/**
 * this variables to hold objects so can delete them later
 */
var all_rect =  new Array();
var all_mark =  new Array();
/**
 * global vars.
 */
var div_width = "45px";
var poly_line_land, poly_line_ship, map ;

/**
 * if when call error like: "google.maps.Overlay is not a constructor" happens
 * then this must be below after google.load() after the initialize()
 */
rectangle_container.prototype = new google.maps.OverlayView();	//OverlayView class is to display custom types of overlay objects on the map

/**
 * this function that initialize the map initially
 */
function initialize() {
    /**
     * map initial options
     */
    var myOptions = {
        zoom: 3,
        center: new google.maps.LatLng(35, -105),
        mapTypeId: google.maps.MapTypeId.ROADMAP,   //ROADMAP , SATELLITE , HYBRID , TERRAIN
        mapTypeControlOptions: {
            style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
        },  //make the above types in drop menu
        navigationControl: true, 	//the zoom, pan control
        navigationControlOptions: {
            style: google.maps.NavigationControlStyle.SMALL, //or this for other styles-->	ANDROID, DEFAULT, SMALL, ZOOM_PAN
            position: google.maps.ControlPosition.TOP_LEFT //or TOP, TOP_LEFT, TOP_RIGHT, BOTTOM, BOTTOM_LEFT, BOTTOM_RIGHT, LEFT, RIGHT
        },
        //to put a scale like every 10cm represent 5okm or any scale
        scaleControl: true,
        scaleControlOptions: {
            position: google.maps.ControlPosition.BOTTOM
        }
    //scrollwheel:false
    //draggable: false 	//if false prevent map from being draggable
    //disableDoubleClickZoom: true	//if false: disables zoom and center on double click
    };
    /**
     * initialize the map on the map_canvas div with above options
     */
    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    /**
     * just define the polyline style & set it to map & no need to put it in array
     * & delete it just we put the new setPath values
     */
    poly_line_land = new google.maps.Polyline({
        strokeColor: '#7CDF43',
        strokeOpacity: 1, //between 0 & 1
        strokeWeight: 6,	//width in pixel
        //there is zIndex if want, compared to other polys.
        map: map
    });
    poly_line_ship = new google.maps.Polyline({
        strokeColor: '#FFFF00',
        strokeOpacity: 1, //between 0 & 1
        strokeWeight: 6,	//width in pixel
        //there is zIndex if want, compared to other polys.
        map: map
    });

}

/**
 * like a contructor that we call it down, to the container rectangle text
 */
function rectangle_container(divcenterpoint, htmltxt, title, opt_color,margin_top) {
    this.div_center_point = divcenterpoint;
    this.html_content = htmltxt;
    this.div_title = title;
    this.bg_color = opt_color;
    this.margin_top = margin_top;
    this.div = null;
}

/**
 * u can implement 3 methods: onAdd(), draw(), and onRemove()
 */
rectangle_container.prototype.onAdd = function() {
    var div = document.createElement('div');
    //div.setAttribute("class", "rectangle_container_div");
    //div.style.border = "1px dotted #BEBEBE";
    div.style.padding = "2px 10px";
    div.style.position = "absolute";
    div.style.color = "#000000";
    div.style.background = this.bg_color;
    div.style.fontSize = "12px";
    div.style.fontWeight = "bold";
    div.style.textAlign = "center";
    div.title = this.div_title;
    //div.style.minWidth = "100px";
    div.innerHTML = this.html_content;
    this.div = div;
    var panes = this.getPanes();	//get all panes, parts layers of the map
    panes.floatPane.appendChild(div);	//floatPane: pane contains the info window. It is above all map overlays
}
rectangle_container.prototype.draw = function() {
    var overlay_projection = this.getProjection();	//return map Projection object associated with this OverlayView.
    var div_center_pt = overlay_projection.fromLatLngToDivPixel(this.div_center_point);	//return the pixel point (x, y) of a LatLng coordinate point
    //this.div.style.width = "auto";
    this.div.style.width = div_width;
    this.div.style.height = "auto";
    var height = this.div.offsetHeight;
    var width = this.div.offsetWidth;
    this.div.style.left = (div_center_pt.x - (width/2)) + "px";	//set div left space which is from the center to 1/2 width
    this.div.style.top = (div_center_pt.y - (height/2)) + "px";	//set div top as from center to the half height multiple the lines number
    if(this.margin_top)
        this.div.style.marginTop = (-1)*(this.margin_top) -(height/2) + 'px';
}
rectangle_container.prototype.onRemove = function() {
    this.div.parentNode.removeChild(this.div);
    this.div = null;
}


/**
 * this function update (refresh) the map & change all drawings to the new values
 * so it draw path bet. the 3 points & cost rectangle in them
 * 
 * the result_array that take it is as this structure:
 * 'Origin' => array([0]=>coord, [1]=>name)
 * 'Middle' => array([0]=>coord, [1]=>name)
 * 'Destination' => array([0]=>coord, [1]=>name)    //if selected
 * 'LandCost' => land_cost_value
 * 'ShipCost' => ship_cost_value
 */
function update_map_draw(result_array) {
    var i=0;
    var car_origin = string_to_LatLng(result_array.Origin[0]);
    var car_middle_port = string_to_LatLng(result_array.Middle[0]);
    if(result_array.Destination)
        var car_destination = string_to_LatLng(result_array.Destination[0]);
    var land_cost = result_array.LandCost;
    var ship_cost = result_array.ShipCost;
    var origin_midlle = null;
    if(result_array.Destination)
        origin_midlle = car_origin;
    else
        origin_midlle = midpoint_LatLng(car_origin, car_middle_port);
    if(result_array.Destination)
        var midlle_destination = midpoint_LatLng(car_middle_port, car_destination);
    /**
     * remove old drawings markers, rectangles,...
     */
    remove_old_map_drawings();
    /**
     * now add the markers to the map & put them in array to delete them before draw new ones
     */
    all_mark.push(
        new google.maps.Marker({
            map: map,
            icon: 'pin.png',
            title: result_array.Origin[1],
            position: car_origin
        })
    );
    all_mark.push(
        new google.maps.Marker({
            map: map,
            //icon: new google.maps.MarkerImage('ship.png',new google.maps.Size(40, 40) ,null,null,new google.maps.Size(40, 40)),
            icon: result_array.Destination?'pin.png':'arrow_down.png',
            title: result_array.Middle[1],
            position: car_middle_port
        })
    );
    if(result_array.Destination)
        all_mark.push(
            new google.maps.Marker({
                map: map,
                icon: 'arrow_down.png',
                title: result_array.Destination[1],
                position: car_destination
            })
        );
    /**
     * add rectangle container that hold the price & push them in array so can delete free them next drawing time
     * the container rectangle that contains the land cost price
     */
    rectangle_container1 = new rectangle_container(origin_midlle,  land_cost+'$', 'Ground Transportation', "#7CDF43",result_array.Destination?35:0);
    rectangle_container1.setMap(map);	//Adds the overlay to the map
    all_rect.push(rectangle_container1);
    /**
     * the container rectangle that contains the ship cost price
     */
    if(result_array.Destination){
        rectangle_container2 = new rectangle_container(midlle_destination,  ship_cost+'$', 'Ocean transportation', "#FFFF00",0);
        rectangle_container2.setMap(map);
        all_rect.push(rectangle_container2);
    }
    /**
     * this to draw the path of the three points
     */
    poly_line_land.setPath([car_origin,car_middle_port]);
    if(result_array.Destination){
        poly_line_ship.setPath([car_middle_port,car_destination]);
        poly_line_ship.setMap(map);
    }
    else
        poly_line_ship.setMap(null);
    /**
     * to let the places (points) fit in the map
     */
    var bounds = new google.maps.LatLngBounds();    //contruct rectangle from 2 points
    bounds.extend(car_origin);
    bounds.extend(car_middle_port);
    if(result_array.Destination)
        bounds.extend(car_destination);
    map.fitBounds(bounds);  //Sets the maps to fit to the given bounds.
}
/**
 * this function return the midpoint of 2 points
 */
function midpoint_LatLng(pt1, pt2){
    var mid_lat = ((pt1.lat() + pt2.lat())/2);
    var mid_lng = ((pt1.lng() + pt2.lng())/2);
    return new google.maps.LatLng(mid_lat, mid_lng);
}
/**
 * this function takes a string of the lat & lng & return it as LatLng object
 */
function string_to_LatLng(point_string){
    point_string = point_string.split(",");
    return new google.maps.LatLng(point_string[0],point_string[1]);

}
/**
 * this to remove clear all old drawings rectangles, polylines,..
 */
function remove_old_map_drawings(){
    /**
     * first remove all old markers in the array
     */
    if(all_mark.length>0) {
        for(i=0; i<all_mark.length; i++){
            all_mark[i].setMap(null);
            all_mark[i] = null;
        }
        all_mark.length = 0;
    }
    /**
     * first remove all old rectangles in the array
     */
    if(all_rect.length>0) {
        for(i=0; i<all_rect.length; i++){
            all_rect[i].setMap(null);
            all_rect[i] = null;
        }
        all_rect.length = 0;
    }
}
/**
 * this to initialize the map after window load
 */
//google.maps.event.addDomListener(window, 'load', initialize);
$(window).load(function(){
    initialize();
})
