(function($) {
  var route = new base2.Package(this, {
    name:    "route",
    version: "1.0",
    parent:  dashfly,
    imports: "dashfly,improving",
    exports: "RouteManager"
  });
  
  eval(this.imports);
  
  ////////to import
  function ProcessAddingAddress(response) {
     if(parseInt(response, 10) === 0) 
     {
        alert('Error occured while adding address to the address book.');
     }
  }
  
  function addAddressToAddressBookImport(address){
     var label = "";
     var data = address;
     var separator = data.indexOf(":");
     if (separator >= 0){
        label = data.substr(0, separator);
        data = data.substring(separator + 1)
     }
     // call backend to add address
     var postContent = '';
     postContent += "label="+ label + "&";
     postContent += "addr=" + data + "&";
     postContent += "lat=0"+ "&";
     postContent += "lon=0";
     jQuery.get(ajaxcall + "addAddress.php", postContent, ProcessAddingAddress);
  }
 /////////////////
  var RouteManager = base2.Base.extend({
	  constructor: function(application) {
	  	  this.application = application;
	  	  this.mapManager = application.getService(map.MapManager);
  	  },

  	  getDirections: function() {
  		  return directionObj;
  	  },
  	  
  	  getDestination: function() {
  		  return routeDestination;
  	  },
  	  
  	  isRoundTrip: function() {
  		  return (this.getDestination() === null);
  	  },
  	  
  	  getRoute: function(withDestination) {
  		  var addresses = addList.slice();
  		  if (withDestination && this.getDestination()) {
  			  addresses.push(this.getDestination());
  		  }
  		  return addresses;
  	  },
  	  
	  canAddAddress: function(existing) {
		  if (existing == Undefined()) {
			  existing = addList.length;
		  }
		  var maxPoints = getMaximumPoints();
		  //var maxSaves = getMaximumSaves();
		  if ($('#roundtrip:checked').length === 0) { --maxPoints; }
		  return Math.max(0, maxPoints - existing);
	  },
	  
	  addAddress: function(address) {
		  if (isShowMyRoute) {
			  var index = this.selectPosition(address);
			  Array2.insertAt(addList, index, address);
			  FindRoute();
		  } else {
			  local = [address];
			  addSearchToRoute(0);  
		  }
		  if (jQuery("#isAddressBookPage").count > 0){
		  this.ensureRouteIsVisible();
		  }
     },
     
	  importAddresses: function(stops, replace, block, context) {
		  if (replace) {
			  addList = [];
			  routePointIndex = 0;
			  goBack();
		  }
	     
		  var available = this.canAddAddress();

		  if (available < stops.length) {
			  alert(stops.length + ' addresses were imported.\r\n' +
				   'However, your account only allows ' + available +
	  	  		   '\r\nadditional stop(s) unless you upgrade.\r\n' +
	  	  		   'The additional stops will be ignored.');
		  } else {
			  available = stops.length;
		  }
	  	  	
		  if (available > 0) {
			  var geocodeAndAdd = function(stops) {
			    if (stops.length > 0) {
			    	var stop = stops.shift();
					var address = new DashFlyAddress();
					var line, city, state, zip, label;
					  
					Base.forEach(stop, function(property, name) {
						switch(name.toLowerCase()) {
							case "address": line = property; break;
							case "city": city = property; break;
							case "state": state = property; break;
							case "zipcode": zip = property; break;
							case "label": label = property; break;
						}
					});
					address.SetAddress([line, city, state, zip].join());
					  
					if (label) {
					   address.SetAddressLabel(label + ':' + address.GetAddress());
					} else {
					   address.SetAddressLabel(address.GetAddress());
					}

					this.mapManager.geocode(address, function(address, success) {
						if (success) { this.addAddress(address); }
			   			if ($.isFunction(block)) {
			   				block.call(context, address, success, stops.length === 0);
			   			}
			   			geocodeAndAdd.call(this, stops);
					}, this);
			    }
			  };
			  geocodeAndAdd.call(this, stops.slice(0, available + 1));
		  }
	  else if ($.isFunction(block)) {
			  block.call(context, null, true, true); 
		  }
	  },
	  
     importAddressesDB: function(stops, replace, block, context) {
        if (replace) {
           addList = [];
           routePointIndex = 0;
           //goBack();
        }
        
        //var maxAddresses = getMaximumAddresses();
        
        //var available = this.canAddAddress();
        var available = 500;
        //var available = getMaximumAddresses();

        if (available < stops.length) {
           alert(stops.length + ' addresses were imported.\r\n' +
               'However, your account only allows ' + available +
               '\r\nadditional address(es) unless you upgrade.\r\n' +
               'The additional addresses will be ignored.');
        } else {
           available = stops.length;
        }
         
        if (available > 0) {
           var geocodeAndAdd = function(stops) {
             if (stops.length > 0) {
               var stop = stops.shift();
               var address = new DashFlyAddress();
               var line, city, state, zip, label;
                 
               Base.forEach(stop, function(property, name) {
                  switch(name.toLowerCase()) {
                     case "address": line = property; break;
                     case "city": city = property; break;
                     case "state": state = property; break;
                     case "zipcode": zip = property; break;
                     case "label": label = property; break;
                  }
               });
               address.SetAddress([line, city, state, zip].join());
                 
               if (label) {
                  address.SetAddressLabel(label + ':' + address.GetAddress());
               } else {
                  address.SetAddressLabel(address.GetAddress());
               }
               addAddressToAddressBookImport(address.GetAddressLabel());/// properly formatted address here
               this.mapManager.geocode(address, function(address, success) {
                  //if (success) { this.addAddress(address); }
                     if ($.isFunction(block)) {
                        block.call(context, address, success, stops.length === 0);
                     }
                     if(stops.length==0){window.location.reload();}
                     geocodeAndAdd.call(this, stops);
               }, this);
             }
           };
           geocodeAndAdd.call(this, stops.slice(0, available + 1));
        }
     else if ($.isFunction(block)) {
           block.call(context, null, true, true); 
        }
     },
	  
     selectPosition: function(address) {
	     var minDistance, afterIndex = 0;
    	  var latlng = address.GetLatLng();
    	  $('ul#stops tr:first-child').each(function(index) {
    		  var stop = $(this).attr('id');
    		  stop = parseInt(stop.substring(stop.lastIndexOf("_")+1), 10);
    		  var distance = addList[stop].GetLatLng().distanceFrom(latlng);
    		  if (index === 0 || distance <= minDistance) {
    			  minDistance = distance;
    			  afterIndex = index;
    		  }		  
    	  });
    	
    	  return (afterIndex === 0) ? 1 : afterIndex;
      },
	  
	  ensureRouteIsVisible: function() {
    	  this.mapManager.centerPointsInMap(Array2.map(addList, function(address) {
    		  return address.GetLatLng();
    	  }));
	  }
  });
    
  var RouteModule = Module.extend({
	  load: function() {
	  	 this.routeManager = new RouteManager(this.application);
	  	 this.addService(this.routeManager);
  	 
	  	 $(delegate(function() {
	  		this.importDialog = $(document.createElement('div'))
	  		  .jqm({toTop: true, modal: false, overlay: 10,
	  			  ajax: this.getUrl().forAction('import'),
	  			  onLoad: delegate(function(hash) {
	  				 this.importDialog.hide().addClass('ui-dialog modalwin').centerInClient();
	  				 $('.tabContainer > ul', this.importDialog).tabs({selected: 0});
	  		 		 $('#import_replace').attr('checked', true);
	  				 this.configureImportFile();
	  				 this.configureImportCSV();
	  				 this.importDialog.show();
	  			  }, this)
	  	 	 });
	  		
			 $('.import_trigger').click(delegate(function() {
				 this.importDialog.jqmShow();
  			 }, this)).show();
			 
	  	     this.importDialog.appendTo(document.body);
	  	 }, this));
  	  },
  	  
	  configureImportFile: function() { //TODO
  	   if (jQuery("#isAddressBookPage").length > 0){ 
   		  $('#import_file_confirm', this.importDialog).click(delegate(function() {
  			  var replace = $('#import_replace', this.importDialog).get(0);
  			  $('input:file', this.importDialog).each(delegate(function(upload) {
				   this.uploadFileDB(upload, replace.checked,
					  delegate(function(stop, success, done) { 
					   	 if (done) { this.importDialog.jqmHide(); } 
					  }, this));
  			  }, this));
  			  return false;
  		  }, this)); 
  	   }
  	   else{
  	    $('#import_file_confirm', this.importDialog).click(delegate(function() {
          var replace = $('#import_replace', this.importDialog).get(0);
          $('input:file', this.importDialog).each(delegate(function(upload) {     
              this.uploadFile(upload, replace.checked,
                delegate(function(stop, success, done) { 
                     if (done) { this.importDialog.jqmHide(); } 
                }, this));
          }, this));
          return false;
       }, this)); 
     }
  	  },
  	  
  	  configureImportCSV: function() {//TODO
  	   if (jQuery("#isAddressBookPage").length > 0){
  		  $('#import_csv_lines', this.importDialog).val(
  			   "Address,City,State,ZipCode,Label\n");
  		  $('#import_csv_confirm', this.importDialog).click(delegate(function() {
  			  var replace = $('#import_replace', this.importDialog).get(0);
  			  this.uploadCSVDB(replace.checked, delegate(function(stop, success, done) { 
					   	 if (done) { this.importDialog.jqmHide(); } 
					  }, this));
  			  return false;
  		  }, this)); 
  	   }
  	   else{
        	$('#import_csv_lines', this.importDialog).val(
             "Address,City,State,ZipCode,Label\n");
         $('#import_csv_confirm', this.importDialog).click(delegate(function() {
            var replace = $('#import_replace', this.importDialog).get(0);
            this.uploadCSV(replace.checked, delegate(function(stop, success, done) { 
                       if (done) { this.importDialog.jqmHide(); } 
                  }, this));
            return false;
         }, this)); 
       }
  	  },

	  uploadFile: function(selector, replace, block, context) {
	      if ($.trim($(selector).val()).length > 0) {
	    	  $.ajaxFileUpload({dataType: 'json', secureuri: false,
	    		  url: this.application.getUrl().forAjax('importAddresses'),
	    		  fileElementId: $(selector).attr('id'),
	    		  success: delegate(function(t, stops, status) {
	    			  this.routeManager.importAddresses(stops, replace, block, context);
	    		  }, this),
	    	  	  error: function(xhr,status,err) {
	    			  alert('Unable to upload addresses : ' + err);
	    	  	  }
	    	  });	
	      }
	  },
	  
	  uploadCSV: function(replace, block, context) {
		  $.ajax({type: 'POST', dataType: 'json',
				  url: this.application.getUrl().forAjax('importAddresses'),
			 	  data: {addresses_csv: $('#import_csv_lines', this.importDialog).val()},
				  success: delegate(function(options,stops,status) {
					this.routeManager.importAddresses(stops, replace, block, context);
				  }, this),
				  error: function(xhr,status,err) {
					 alert('Unable to upload addresses : ' + err);
			      }
		  });
	   },
	   
     uploadFileDB: function(selector, replace, block, context) {//TODO
        if ($.trim($(selector).val()).length > 0) {
          $.ajaxFileUpload({dataType: 'json', secureuri: false,
             url: this.application.getUrl().forAjax('importAddresses'),
             fileElementId: $(selector).attr('id'),
             success: delegate(function(t, stops, status) {
                this.routeManager.importAddressesDB(stops, replace, block, context);
             }, this),
             error: function(xhr,status,err) {
                alert('Unable to upload addresses : ' + err);
             }
          }); 
        }
    },
	  
     uploadCSVDB: function(replace, block, context) {//TODO
	        $.ajax({type: 'POST', dataType: 'json',
	              url: this.application.getUrl().forAjax('importAddresses'),
	              data: {addresses_csvdb: $('#import_csv_lines', this.importDialog).val()},
	              success: delegate(function(options,stops,status) {
	               this.routeManager.importAddressesDB(stops, replace, block, context);
	              }, this),
	              error: function(xhr,status,err) {
	                alert('Unable to upload addresses : ' + err);
	               }
	        });
	      }
	  
  });
  if (jQuery("#isAddressBookPage").length > 0){ 
     location.reload;
  }
  
  eval(this.exports);
})(jQuery);
