/**
 * MarkerTracker v1.0
 * Copyright (c) 2008 Dan Rummel
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 *
 *
 * Author: Dan Rummel (www.seero.com)
 *
 *  This ulitily displays directional indicators for "important" markers
 *  on that are out of your maps view.
 */


/**
 *  Creates a MarkerTracker for the given marker and displays it ont he map as needed.
 *
 * @constructor
 * @param {Map} map The map that will display the MarkerTracker. 
 * @param {GMarker} marker the marker to be tracked.
 * @param {Object} opts? Object that contains the options for coustomizing the 
 *                  look and behavior of arrows:
 *   {Number} iconScale Scales the icon size by this value, 0 = no icon.
 *   {Number} padding The padding between the arrow and the edge of the map.
 *   {String} color Color of the arrow.
 *   {Number} weight Thickness of the lines that make up the arrows.
 *   {Number} length length of the arrow.
 *   {Number} opacity opacity of the arrow.
 *   {String} updateEvent The GMap2 event name that triggers the arrows to update.
 *   {String} panEvent The GMarker event name that triggers a quick zoom to the tracked marker.
 *   {Boolean} quickPanEnabled The GMarker event name that triggers a quick zoom to the tracked marker.
 */

function MarkerTracker(marker, map, opts) {
  this.map_ = map;
  this.marker_ = marker;
  this.enabled_ = false;
  this.arrowDisplayed_ = false;
  this.arrow_ = null;
  this.oldArrow_ = null;
  this.control_ = null;
  
  // setup the options
  opts = opts || {};
  this.iconScale_ = MarkerTracker.DEFAULT_ICON_SCALE_;
  if (opts.iconScale != undefined ) {
    this.iconScale_ = opts.iconScale;
  }
  this.padding_ = MarkerTracker.DEFAULT_EDGE_PADDING_;
  if (opts.padding != undefined ) {
    this.padding_ = opts.padding;
  }
  this.color_ = MarkerTracker.DEFAULT_ARROW_COLOR_;
  if (opts.color != undefined ) {
    this.color_ = opts.color;
  }
  this.weight_ = MarkerTracker.DEFAULT_ARROW_WEIGHT_;
  if (opts.weight != undefined ) {
    this.weight_ = opts.weight;
  }
  this.length_ = MarkerTracker.DEFAULT_ARROW_LENGTH_;
  if (opts.length != undefined ) {
    this.length_ = opts.length;
  }
  this.opacity_ = MarkerTracker.DEFAULT_ARROW_OPACITY_;
  if (opts.opacity != undefined ) {
    this.opacity_ = opts.opacity;
  }
  this.updateEvent_ = MarkerTracker.DEFAULT_UPDATE_EVENT_;
  if (opts.updateEvent != undefined ) {
    this.updateEvent_ = opts.updateEvent;
  }
  this.panEvent_ = MarkerTracker.DEFAULT_PAN_EVENT_;
  if (opts.panEvent != undefined ) {
    this.panEvent_ = opts.panEvent;
  }
  this.quickPanEnabled_ = MarkerTracker.DEFAULT_QUICK_PAN_ENABLED_;
  if (opts.quickPanEnabled != undefined ) {
    this.quickPanEnabled_ = opts.quickPanEnabled;
  }
  
  //replicate a different sized icon 
  var babyIcon = new GIcon(marker.getIcon());
  babyIcon.iconSize = new GSize( 
    marker.getIcon().iconSize.width * this.iconScale_,
    marker.getIcon().iconSize.height * this.iconScale_ );
  babyIcon.iconAnchor = new GPoint( 
    marker.getIcon().iconAnchor.x * this.iconScale_,
    marker.getIcon().iconAnchor.y * this.iconScale_/2);
  // kill the shadow
  babyIcon.shadow = null;
  this.babyMarker_ = new GMarker(new GPoint(0, 0), babyIcon);
  
  //bind the update task to the event trigger
  GEvent.bind(this.map_, this.updateEvent_, this, this.updateArrow_ );
  //update the arrow if the marker moves
  GEvent.bind(this.marker_, 'changed', this, this.updateArrow_ );
  if (this.quickPanEnabled_) {
    GEvent.bind(this.babyMarker_, this.panEvent_, this, this.panToMarker_ );
  }
  
  //do an inital check
  this.updateArrow_();
};


//Default Arrow Constants
MarkerTracker.DEFAULT_EDGE_PADDING_ = 25;
MarkerTracker.DEFAULT_ICON_SCALE_ = 0.6;
MarkerTracker.DEFAULT_ARROW_COLOR_ = '#ff0000';
MarkerTracker.DEFAULT_ARROW_WEIGHT_ = 20;
MarkerTracker.DEFAULT_ARROW_LENGTH_ = 20;
MarkerTracker.DEFAULT_ARROW_OPACITY_ = 0.8;
MarkerTracker.DEFAULT_UPDATE_EVENT_ = 'move';
MarkerTracker.DEFAULT_PAN_EVENT_ = 'click';
MarkerTracker.DEFAULT_QUICK_PAN_ENABLED_ = true;

//Default Control Constants

/**
 *  Disables the marker tracker.
 */
MarkerTracker.prototype.disable = function() {
  this.enabled_ = false;
  this.updateArrow_();
};

/**
 *  Enables the marker tracker.
 */
MarkerTracker.prototype.enable = function() {
  this.enabled_ = false;
  this.updateArrow_();
};

/**
 *  Called on on the trigger event to update the arrow. Primary function is to
 *  check if the parent marker is in view, if not draw the tracking arrow.
 */

MarkerTracker.prototype.updateArrow_ = function() {
  if(!this.map_.getBounds().containsLatLng(this.marker_.getLatLng()) && this.enabled_) {
    this.drawArrow_();
  } else if(this.arrowDisplayed_) {
    this.hideArrow_();
  }
};



/**
 *  Draws or redraws the arrow as needed, called when the parent marker is
 *  not with in the map view.
 */

MarkerTracker.prototype.drawArrow_ = function() {

  //convert to pixels
  var bounds = this.map_.getBounds();
  var SE = this.map_.fromLatLngToDivPixel(bounds.getSouthWest());
  var NE = this.map_.fromLatLngToDivPixel(bounds.getNorthEast());
  //include the padding while deciding on the arrow location
  var minX =  SE.x + this.padding_;
  var minY =  NE.y + this.padding_;
  var maxX =  NE.x - this.padding_;
  var maxY =  SE.y - this.padding_;
  
  // find the geometric info for the marker realative to the center of the map
  var center = this.map_.fromLatLngToDivPixel(this.map_.getCenter());
  var loc = this.map_.fromLatLngToDivPixel(this.marker_.getLatLng());
  
  //get the slope of the line
  var m = (center.y-loc.y) / (center.x-loc.x);
  var b = (center.y - m*center.x);
  
  // end the line within the bounds
  if ( loc.x < maxX && loc.x > minX ) {
    var x = loc.x;
  } else if (center.x > loc.x) {
    var x = minX; 
  } else {
    var x = maxX;
  }

  //calculate y and check boundaries again  
  var y = m * x + b;
  if( y > maxY ) {
    y = maxY;
    x = (y - b)/m;
  } else if(y < minY) {
    y = minY;
    x = (y - b) / m;
  }
  
  // get the proper angle of the arrow
  var ang = Math.atan(-m);
  if(x > center.x ) {
    ang = ang + Math.PI; 
  } 
  
  // define the point of the arrow
  var arrowLoc = this.map_.fromDivPixelToLatLng(new GPoint(x, y));
  
  // left side of marker is at -1,1
  var arrowLeft = this.map_.fromDivPixelToLatLng( 
            this.getRotatedPoint_(((-1) * this.length_), this.length_, ang, x, y) );
            
  // right side of marker is at -1,-1
  var arrowRight = this.map_.fromDivPixelToLatLng( 
            this.getRotatedPoint_(((-1)*this.length_), ((-1)*this.length_), ang, x, y));
  
  
  var center = this.map_.getCenter();
  var loc = this.marker_.getLatLng();
  
  this.oldArrow_ = this.arrow_;
  this.arrow_ = new GPolyline([arrowLeft, arrowLoc, arrowRight],
                this.color_, this.weight_, this.opacity_) ;
  this.map_.addOverlay(this.arrow_);
  
  // move the babyMarker to -1,0
  this.babyMarker_.setLatLng(this.map_.fromDivPixelToLatLng( 
            this.getRotatedPoint_(((-2)*this.length_), 0, ang, x, y)));
          
  if (!this.arrowDisplayed_) {
    this.map_.addOverlay(this.babyMarker_);
    this.arrowDisplayed_ = true;
  }
  if (this.oldArrow_) {
    this.map_.removeOverlay(this.oldArrow_);
  }
};



/**
 *  Hides the arrows.
 */
 
MarkerTracker.prototype.hideArrow_ = function() {
  this.map_.removeOverlay(this.babyMarker_);
  if(this.arrow_) {
    this.map_.removeOverlay(this.arrow_);
  }
  if(this.oldArrow_) {
    this.map_.removeOverlay(this.oldArrow_);
  }
  this.arrowDisplayed_ = false;
};


/**
 *  Pans the map to the parent marker.
 */

MarkerTracker.prototype.panToMarker_ = function() {
  this.map_.panTo(this.marker_.getLatLng());
};

/**
 *  This applies a counter-clockwise rotation to any point.
 *  
 * @param {Number} x The x value of the point.
 * @param {Number} y The y value of the point.
 * @param {Number} ang The counter clockwise angle of rotation.
 * @param {Number} xoffset Adds a position offset to the x position.
 * @param {Number} yoffset Adds a position offset to the y position.
 * @return {GPoint} A rotated GPoint.
 */

MarkerTracker.prototype.getRotatedPoint_ = function(x, y, ang, xoffset, yoffset) {
  var newx = y * Math.sin(ang) - x * Math.cos(ang) + xoffset;
  var newy = x * Math.sin(ang) + y * Math.cos(ang) + yoffset;
  var rotatedPoint = new GPoint(newx, newy);
  return(rotatedPoint);
};
 
$(document).ready(function(){

	$("ul.dropdown li").dropdown();

});

$.fn.dropdown = function() {

	$(this).hover(function(){
		$(this).addClass("hover");
		$('> .dir',this).addClass("open");
		$('ul:first',this).css('visibility', 'visible');
	},function(){
		$(this).removeClass("hover");
		$('.open',this).removeClass("open");
		$('ul:first',this).css('visibility', 'hidden');
	});

}

$(function() {
		$("#start_date").datepicker({ showAnim: 'slide', changeMonth: true, changeYear: true, showOn: 'both', buttonImage: 'images/calendar.gif', buttonImageOnly: true, altFormat: 'yy-mm-dd', dateFormat: 'yy-mm-dd'})
        $("#end_date").datepicker({ showAnim: 'slide', changeMonth: true, changeYear: true, showOn: 'both', buttonImage: 'images/calendar.gif', buttonImageOnly: true, altFormat: 'yy-mm-dd', dateFormat: 'yy-mm-dd'});        
        
    var hide_all = function(link, link_name) {
        $("#personal_link").attr("class", "tab_link");
        $("#user_info_link").attr("class", "tab_link");
        $("#" + link_name).attr("class", "tab_link tab_selected");            
        
        $("#personal").hide();
        $("#userinformation").hide();            
        
        $("#personal").hide();
        $("#userinformation").hide();            
        
        
        $("#" + link).show();           
        return  false;
    }        
    $("#personal_link").bind("click", function() { return hide_all("personal", 'personal_link')});
    $("#user_info_link").bind("click", function() {return  hide_all("userinformation", 'user_info_link')});    
        
    // login    
    // Expand Panel
	$(".login").click(function(){
		$("div#panel").slideDown("slow");	
	});	
 
	// Collapse Panel
	$("#cancel").click(function(){
        $("#loginerror").html('');
		$("div#panel").slideUp("slow");	
        
	});		
    
    var v = $("#login_form").validate({        
        errorPlacement: function(error, element) {
    		element.siblings("p.error").remove();
    		element.parent().addClass('error');            
            element.siblings("label").attr("title", error.html());
            element.attr("title", error.html());
        },
		errorElement: 'p class="no-label error"',
        onkeyup: false,
        onblur: false,
        submitHandler: function() {
            $("#loginerror").html('');
           var data = $("#login_form").serialize(); 
            $.ajax({
                url: 'login.php?a=login',
                dataType: "json",
                data: data,
                type: "POST",
                success: function(response) {
                    if(response.result == 'refresh') {
                        window.location.reload();
                    }
                    else {
                        $("#loginerror").html(response.result);
                    }                   
                }

            });
            return false;
        }
	});

    var v = $("#property_form").validate({        
        errorPlacement: function(error, element) {
            element.siblings("p.error").remove();
            element.parent().addClass('error');            
            element.siblings("label").attr("title", error.html());
            element.attr("title", error.html());
            //error.insertAfter(element);
        },
        onkeyup: false,
        onblur: false,
        rules: {
            about_property: {               
                maxlength: 500
            },
            zip_code: {
                digits:false
            },
            start_date:{
                required:true,
                dateISO: true
            },
            end_date:{
                required:true,      
                dateISO: true,                
                endDate: true
            }
        },
        submitHandler: function(form) {        	
           form.submit();
        }
	});
    
    var v = $("#personal_form").validate({        
        errorPlacement: function(error, element) {element.siblings("p.error").remove();element.parent().addClass('error');
        element.siblings("label").attr("title", error.html());
            element.attr("title", error.html());},
        onkeyup: false,
        onblur: false,
        rules: {
            about: {                
                maxlength: 500
            },
            zip_code: {
                digits:false
            }            
        },
        submitHandler: function(form) {
           form.submit();
        }
	});
    
    $('label.required').append('&nbsp;<strong>*</strong>&nbsp;');
    
    $("#booking").bind('submit', function(){
    	$("#bookingerror").html('');
        var data = $("#booking").serialize();
        if($(".availdates").length == 0) {
        	alert('No available dates are selected to book this property.');
        	return false;
        }
        $.ajax({
    	     url: 'bookings.php',	         
    	     data: data,
    	     type: "POST",
    	     success: function(response) {
        		if (response.indexOf("<h3>Confirmation</h3>") != -1) {
        			$("#booking_div").html(response);
        		}
        		else {
        			$("#bookingerror").html(response);
        		}        		
    	     	return false;
    	     }
       });
       return false;    
    });
    
    
    
    var v = $("#search").bind('submit', function() {        
          if(searchvalidation() == false) {
    		  return false;
    	  }    	  
          $("#search").unbind('submit');
          $("#search").append('<input type="hidden" name="Findproperties" value="Find Properties" />');
    	  $("#search").submit();
    	  return false;        
	});    
});
var searchvalidation = function() {
	/*if($('#country').val() == '') {
		  alert('You need to select Country.');
		  return false;
	  }
	  if($('#state').val() == '') {
		 // alert('You need to select state.');
		  //return false;
	  }*/
	  if($('#city').val() == '') {
		  alert('You need to enter your destination.');
		  return false;
	  }	  
	  
	  if (($("#availcal").html() != null && $("#availcal").html() != 'undefined') && 
			$("#match_exact").attr("checked") != 'undefined' && $("#match_exact").attr("checked") == true) {
		  if ($(".seldates").length == 0) {
			  alert('You need to select date');
			  return false;
		  }
	  }
	  
	  
	  return true;
}

var toggle_form = function(wizard, target_id) {
    current = (target_id - 1);
    wizard.accordion("activate", current);
    return false;
}

var get_info = function() {
	
        var state_text = $("#state").val();
        var city_text = $("#city").val();	
	var country_txt = $("#country").val();
    var info = '<p>' + $('#firstName').val() + '  ' + $('#lastName').val() + '</p><p>' + $('#address1').val() + '<br />' + city_text + ', ' + state_text  + ' ' + $('#zip_code').val() + ' ' + country_txt +'</p>';
    $("#userinfo").html(info);
    
    var info = '<p>' + $('#nameoncard').val() + '<br />' + $('#caddress1').val() + '  ' + $('#caddress2').val() + '<br />' + $('#ccity').val() + ', ' + $('#cstate').val() + ' ' + $('#ccountry').val() + ' ' +  $('#zip_code').val() + '</p><p>' + $('#card_type').val() + '<br />' + $('#card_number').val() + '<br />Exp Date ' + $('#emonth').val() + '/' + $('#eyear').val() + '</p>';
     $("#creaditinfo").html(info);
}
var map = '';var searchStr="";var baseIcon = '';var geocoder = '';
var map_init = function(map_canvas, lat, long) {
	var mapcanvas = document.getElementById("map_canvas");
	var searchStr="";
	if (GBrowserIsCompatible()) {
		map = new GMap2(mapcanvas);
	    map.setCenter(new GLatLng(lat, long), 12);
		//map.setCenter(new GLatLng('37.4419', '-122.1419'), 12);
		map.addControl(new GLargeMapControl3D());
	    map.addControl(new GMapTypeControl());   
	    geocoder = new GClientGeocoder();
	    
	    baseIcon = new GIcon(G_DEFAULT_ICON);
	    baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
	    baseIcon.iconSize = new GSize(20, 34);
	    baseIcon.shadowSize = new GSize(37, 34);
	    baseIcon.iconAnchor = new GPoint(9, 34);
	    baseIcon.infoWindowAnchor = new GPoint(9, 2);   
		/*GEvent.addListener(map,'moveend',function(){              
	        mapresult();
	    });*/
		GEvent.addListener(map,'zoomend',function(){                
		  mapresult();               
		});		
	}                
}

// Creates a marker whose info window displays the letter corresponding
// to the given index.
var createMarker = function(point, name, address, type,imgname,login,bedrooms,bathrooms,pid, guests,puserid) {
//var createMarker = function(store) {
  // Create a lettered icon for this point using our icon class
  var letter1="";
  var letter ="<table cellpading='0' cellspacing='2' width='300' border='0'><tr><td width='80'><img src='"+imgname+"'></td><td valign='top' align='left'>" +name+ "<br />" +address+ "</td></tr>";
  if(login==1) {
	   letter1 ="<tr><td colspan='2'>"+bedrooms+" Bedrooms<br />Max Number of people: " + guests +"</td></tr>";
  }
  
  var letter2 = "<tr><td colspan='2'><a href='pdetails.php?pid="+pid+"' class=\"button\" style=\"margin-right:0px;float:right;\">View Property</a></td></tr></table>";
  var show_address = letter+" "+letter1+" "+letter2;
  var letteredIcon = new GIcon(baseIcon); 
  if(logUser==puserid) {
	  //letteredIcon.image = "http://maps.illinoisstate.edu/images/markers/facilitiesMarker.png";
	  letteredIcon.image = "images/marker.png";
  }
  else {
	  letteredIcon.image = "http://www.google.com/mapfiles/marker.png";
  } 
  // Set up our GMarkerOptions object
  markerOptions = { icon:letteredIcon };
  var marker = new GMarker(point, markerOptions);

  GEvent.addListener(marker, "click", function() {
    //marker.openInfoWindowHtml("<b>" + show_address + "</b>");
	//jQuery.facebox(show_address);	
	//jQuery.facebox({ ajax: 'show_properties.php?lat=' + point.lat() + '&long=' + point.lng()})
	return false;
  });
  return marker;
}
 
var showAddress = function(address) {	
    if (!geocoder) return;
    geocoder.getLatLng(address, function(point) {    	
      if (!point) {
    	  alert(address + " not found");
      }
	  else {			  
         map.setCenter(point, 12);			 
      }	  
	  mapresult();    
     }
   );
}
var locations = {};
function mapresult () {
	locations = {};
	map.clearOverlays(); 
	// Add 10 markers to the map at random locations		
	var centerLatLong = map.getCenter();		
	var bounds = map.getBounds();		
	var southWest = bounds.getSouthWest();
	var northEast = bounds.getNorthEast(); 	
	var nelat = northEast.lat();
	var nelng = northEast.lng();
	var swlat = southWest.lat();
	var swlng = southWest.lng();
	var url ="search-map.php?nelat="+nelat+"&nelng="+nelng+"&swlat="+swlat+"&swlng="+swlng+"&"+searchStr+"&centerLatLong="+centerLatLong;
	GDownloadUrl(url, function(data) {	
		locations = {};
		var xml = GXml.parse(data);
		var markers = xml.documentElement.getElementsByTagName("marker");
		
		for (var i = 0; i < markers.length; i++) {
			var name = markers[i].getAttribute("name");
			var address = markers[i].getAttribute("address");
			var type = markers[i].getAttribute("type");
			var imgname = markers[i].getAttribute("imgname");	
			var login = markers[i].getAttribute("login");
			var bedrooms = markers[i].getAttribute("bedrooms");
			var bathrooms = markers[i].getAttribute("bathrooms"); 
			var guests = markers[i].getAttribute("guests");
			var pid = markers[i].getAttribute("pid");
			var puserid = markers[i].getAttribute("puserid");
			var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng")));		
			// map.addOverlay(createMarker(point, i));
			//var marker = createMarker(point, name, address, type,imgname,login,bedrooms, bathrooms,pid,guests,puserid);
			//map.addOverlay(marker);
			var store = {latlng: point, name: name, address: address, type: type, imgname:imgname, 
						login:login, bedrooms:bedrooms, bathrooms:bathrooms, guests:guests, pid:pid, 
						puserid:puserid};
  		    var latlngHash = (point.lat().toFixed(6) + "" + point.lng().toFixed(6));
			latlngHash = latlngHash.replace(".","").replace(".", "").replace("-","");
			
			if (locations[latlngHash] == null) {
				locations[latlngHash] = []
			}
			locations[latlngHash].push(store);
		 }
		 var mt  = [];
		 for (var latlngHash in locations) {
				var stores = locations[latlngHash];
				var m = createClusteredMarker(stores);
				map.addOverlay(m);			
				mt[mt.length] = new MarkerTracker(m, map);

     }
		 $("#count_property").html(markers.length);

	});
}

function stripslashes(str) {
	str=str.replace(/\\'/g,'\'');
	str=str.replace(/\\"/g,'"');
	str=str.replace(/\\0/g,'\0');
	str=str.replace(/\\\\/g,'\\');
	return str;
}
function createClusteredMarker(stores) {
  var point = stores[0].latlng;
  var tabs = [];  
  var puserid = '';

  for (var i = 0; i < stores.length; i++) {
		//stores[i].name = stores[i].name.replace("'", "\\'")		
	  var html = [];
	  html[html.length] ="<table cellpading='0' cellspacing='2' width='300' border='0'><tr><td width='80'>";
	  html[html.length] = '<img src="'+stores[i].imgname+'"></td><td valign="top" align="left">' +stores[i].name+ '<br />' +stores[i].address+ "</td></tr>";
	  if(stores[i].login==1) {
	    html[html.length] = "<tr><td colspan='2'>"+stores[i].bedrooms+" Bedrooms<br />Max Number of people: " + stores[i].guests +"</td></tr>";
	  }	  
	  html[html.length] = "<tr><td colspan='2'><a href='pdetails.php?pid="+stores[i].pid+"' class=\"button\" style=\"margin-right:0px;float:right;\">View Property</a></td></tr></table>";
	  var show_address = stripslashes(html.join("\n"));	  	  
	  tabs.push(new GInfoWindowTab('Apt #' + (i + 1), show_address));
		puserid = stores[i].puserid		
  }
  
  var letteredIcon = new GIcon(baseIcon); 
  if(logUser == puserid) {		  
	  letteredIcon.image = "images/marker.png";
  }
  else {
	  letteredIcon.image = "http://www.google.com/mapfiles/marker.png";
  } 	  
  if (stores.length > 1) {
	letteredIcon.image = "images/m.png";
  }
  
  // Set up our GMarkerOptions object
  markerOptions = { icon:letteredIcon };
  var marker = new GMarker(point, markerOptions);  
  //marker.openInfoWindowTabsHtml(tabs);    
  GEvent.addListener(marker, "click", function() {
		marker.openInfoWindowTabsHtml(tabs);     
		return false;
  });
  return marker;
}










