﻿var VehiclesController=Class.create(BookingsTab,
{
	initialize:function($super,Containers,Observables,Buttons,NotifyDiv,MsgController,AjaxCallDiv,TabMapper)
	{
		$super(TABS['VEHICLES'],Containers,Observables,Buttons,NotifyDiv,MsgController,TabMapper);
		this.ACTIONTYPE={VERIFYVEHDETAILS:512,GETVEHICLEDIMENSIONS:1024,DRIVERCHANGE:2048};
		this.REQUESTTYPE={UPDATEVEHICLE:1,GETVEHICLEDETAILS:2};
		this.MESSAGES=	{
							RegistrationNumberMissing	:1301,
							ChassisNumberMissing		:1302,
							RegistrationNumberTooLong	:1303,
							ChassisNumberTooLong		:1304,
							NoDriverSelected			:1305,
							NoVehicleModelSelected		:1306,
							InvalidFare					:4000
						};
		this.selVeh=null;
		this.selVehRow=-1;
		this.InstanceName='insVehicleController';
		this.AjaxCallDiv=$(AjaxCallDiv);
		this.VehTypeCodes={Car:1,HvyVeh:2,Trailer:4,MotorBike:8};
		this.VehicleReservations=new VehicleReservationCollection();
		this.VehicleTypes=new Hash();//These are used for the drop down list
		this.Vehicles=new Vehicles();//This is an object which contains the information about every vehicle type selected, added dynamically
		this.DriversCollection=null;
		//this.initialVehicleReservations=new VehicleReservationCollection(); //080802 - this is reset back if the back button is pressed
		this.isDisabled=false;
		this.ButtonColl.enableButtons(TabMovDir['BCK']); //enable the previous buttons
		this.SpecialOfferList=new SpecialOffers
		this.blnSpecialOffer=false;
	},// end initialize
	resetControls: function(FromBackEnd)
	{
		try
		{
		this.MsgController.ClearServerMessageContainer(); //clear out messages
		if (FromBackEnd)
		{
			this.VehicleReservations=new VehicleReservationCollection();
		}

	//	this.VehicleReservations.setReservations(this.initialVehicleReservations.getReservations().clone()); //reset at it back to what was recieved from ze numbers tab :)

		//NO NO NO THIS IS SET FROM THE NUMBERS TAB CANNOT JUST DELETE IT :)
		//this.VehicleReservations=new VehicleReservationCollection();
		this.VehList.buildResTable(0,this.VehicleReservations.getIniReservations());
		this.DriversCollection=null;
		this.selVeh=null;
		this.selVehRow=-1;
		this.isDisabled=false;
		this.VehDetails.resetControls();
		this.DisableControls();
		this.blnSpecialOffer=false;
	 }
	 catch (err)
	 {
	 	alert(err);
	}

	},//end resetControls - 080802 [DA]
	setVehicleVerified: function(Value)
	{
		this.selVeh.isVerified=Value;
		if (!Value) //otherwise leave them as you found them :)
			this.ButtonColl.disableButtons(TabMovDir['FWD']);
	},//setVehicleVerified
	HandleUpdateVehResponse: function(SelectedVehStatus,Fare,IsValidFare)
	{
		this.selVeh.isSaved=SelectedVehStatus;
		if (this.selVeh.isSaved)
		{
			if (IsValidFare)
			{
				this.selVeh.fare=Fare;
				this.VehList.buildResTable(this.selVehRow,this.VehicleReservations.getReservations());
			}
			else
			{
					this.MsgController.ShowLocalMsgs([this.MESSAGES['InvalidFare']]);
					this.setVehicleVerified(false);
					//this.ButtonColl.disableButtons();
			}
		}
		this.CheckAndContinue();
	}, //end HandleUpdateVehResponse
	CheckAndContinue: function()
	{
		var blnTest=true;
		try
		{
			this.VehicleReservations.getReservations().each(function(i)
			{
				var veh=i.value;
				if (!veh.isVerified || !veh.isSaved)
				{
					blnTest=false;
					throw $break;
				}
			},this)
		}
		catch (err)
		{
			blnTest=false;
		}
		//if (blnTest && this.blnSpecialOffer)	
		if (blnTest && this.blnSpecialOffer)	
			this.ButtonColl.enableButtons(TabMovDir['FWD']);
		else
			this.ButtonColl.disableButtons(TabMovDir['FWD']);
	},//end CheckAndContinue
	SetActiveVehicle: function(resvId,row)
	{
		this.selVeh=this.VehicleReservations.getReservation(resvId);
		this.VehDetails.SetVehicle(this.selVeh);
		this.selVehRow=row-1;
		this.selVeh.clickedOnce=true; //from now on read the items in the forms
	},//end SetActiveVehicle
	HasVehicleReservations: function()
	{
		return (this.VehicleReservations.getNumReservations() > 0);
	},//end HasVehicleReservations
	AddVehicleTypesCollection: function(VehicleTypesCollection)
	{
		this.VehicleTypes.set(VehicleTypesCollection.TypeCode,VehicleTypesCollection);
	},//end AddVehTypesColl
	SetVehicleReservationCollection: function(VehicleReservationCollection,BookingId)
	{
		//this.initialVehicleReservations.setReservations(VehicleReservationCollection.clone()); //080802 - this is reset back if the back button is pressed - its important to clone it otherwise changes in one will afect the other -STILL NOT WORKING RIGHT!!
		this.VehicleReservations.setReservations(VehicleReservationCollection);
		this.VehList.setBookingId(BookingId);
	},//end SetVehicleReservationCollection
	AddVehicle: function(Vehicle)
	{
		this.Vehicles.AddVehicle(Vehicle);
		this.VehDetails.setVehicleDimensionText(Vehicle.Id);
	},
	setAndInitDrivers: function(DriverCollection)
	{
		this.DriversCollection=DriverCollection;
		this.VehList.buildResTable(0,this.VehicleReservations.getIniReservations()); //080802 - Setting from the cloned one - This is important!!
		this.VehDetails.enableControls();
		this.VehDetails.SetDrivers(this.DriversCollection);
		this.selVeh=this.VehicleReservations.getFirstReservation();
		this.selVehRow=0; //Automatically select the passenger at row 0
		this.selVeh.clickedOnce=true;
		this.VehDetails.setTitle(this.selVeh.ReservationId);
		this.VehDetails.SetVehicleModels(this.VehicleTypes.get(this.selVeh.VehicleTypeCode));
	},//end setAndInitDrivers
	setSelVehDriver: function(idx)
	{
		//var checkDriver=this.DriversCollection.isDriverAssigned(idx);
		if (this.DriversCollection.isDriverAssigned(idx))
		{
			var drv=this.DriversCollection.getDriver(idx);
			var carResvNumber=drv.carResvNumber;
			var vehicleReservation=this.VehicleReservations.getReservation(carResvNumber);
			drv.setCarResvNumber(0);
			vehicleReservation.Driver=null; //reset it - in this way preventing the same driver from having 2 different cars
			vehicleReservation.isSaved=false;
			vehicleReservation.isVerified=false;
		}
		this.DriversCollection.getDriver(idx).setCarResvNumber(this.selVeh.ReservationId);
		this.selVeh.Driver=this.VehDetails.getDriver(this.DriversCollection);
	},
	setRequest: function(requestType,args)
	{
		try
		{
			Element.show($(this.NotifyDiv));
			this.MsgController.ClearServerMessages();
			switch (requestType)
			{
				case this.REQUESTTYPE['UPDATEVEHICLE']:
				{
					this.UpdateVehicleRequest($(this.NotifyDiv));
					break;
				}
				case this.REQUESTTYPE['GETVEHICLEDETAILS']:
				{
					var vehId=args;
					this.SetVehicleDetailsRequest($(this.NotifyDiv),vehId);
					break;
				}
				//NJF - 04092009
						case this.REQUESTTYPE['SPECIALOFFER']:
						{
							this.blnSpecialOffer = false;
							this.GetSpecialOffersRequest($(this.NotifyDiv));
							break;
						}
			}
		}
		catch (err)
		{
			alert(err)
			return false;
		}
	},//end setRequest
	//NJF - 04092009
 		GetSpecialOffersRequest: function(NotifyContainer)
		{
			try
			{
				new Ajax.Updater(this.AjaxCallDiv,this.url,
				{
					method: 'post',
					evalScripts: true,
					parameters:
					{
						ajaxLoad:	REQUESTTYPE['SPECIALOFFER'],
						BookingId:	this.VehList.getBookingId(),
						Type:		'V'
					},
					onComplete: function(transport) //note this keyword will not work in here
					{
						Element.hide(NotifyContainer);
					}
				});
			}
			catch(err)
			{
				alert(err);
			}
		},//end GetSpecialOffersRequest
		//setSpecialOffer: function(OfferId,OfferRate,OfferDescription)
		setSpecialOffer: function(OfferId,OfferRate,OfferDescription,OfferLink,OfferNotice,OfferFareBasis,Entitlement,VehicleOfferRate,VehicleOfferFareBasis,VehicleOfferEntitlement)
		{	
			this.SpecialOfferList.OfferId=OfferId;
			this.SpecialOfferList.OfferRate=OfferRate;
			this.SpecialOfferList.OfferDescription=OfferDescription;
			this.SpecialOfferList.OfferLink=OfferLink;
			this.SpecialOfferList.OfferNotice=OfferNotice;
			this.SpecialOfferList.OfferFareBasis=OfferFareBasis;
			this.SpecialOfferList.OfferEntitlement=Entitlement;
			this.SpecialOfferList.VehicleOfferRate=VehicleOfferRate;
			this.SpecialOfferList.VehicleOfferFareBasis=VehicleOfferFareBasis;
			this.SpecialOfferList.VehicleOfferEntitlement=VehicleOfferEntitlement;
			this.blnSpecialOffer = true; 
			this.CheckAndContinue();		
		},//end setSpecialOffer
	UpdateVehicleRequest: function(NotifyContainer)
	{
		var DateRet;
		if (this.TabMapper.RouteTab.IsExcursion)
			DateRet=this.TabMapper.RouteTab.DateOut.getTripDate();
		else
			DateRet=(this.TabMapper.RouteTab.DateRet.hasDates() ? this.TabMapper.RouteTab.DateRet.getTripDate():-1);

		new Ajax.Updater(this.AjaxCallDiv,this.url,
		{

			method: 'post',
			evalScripts: true,
			parameters:
			{
				ajaxLoad:			REQUESTTYPE['UPDATEVEH'],
				VoyIdOut:			this.TabMapper.RouteTab.outVoyage.getVoyageId(),
				VoyIdRet:			this.TabMapper.RouteTab.retVoyage.getVoyageId(),
				VoyPartOut:			this.TabMapper.RouteTab.outVoyage.getVoyagePartId(),
				VoyPartRet:			this.TabMapper.RouteTab.retVoyage.getVoyagePartId(),
				DateOut:			this.TabMapper.RouteTab.DateOut.getTripDate(),
				DateRet:			DateRet, //if it has date otherwise -1
				OpenEnded:			(this.TabMapper.RouteTab.IsOpenEnded() ? 1 : 0),
				ReservationId:		this.selVeh.ReservationId, //This is the actual reservaiton id in the reservationscars table
				DriverReservationId:this.selVeh.Driver.passResvNumber,
				CarReservationvId:	this.selVeh.CarReservationId, //This is the CarReservationId Column
				bookingId:			this.VehList.getBookingId(),
				RegistrationNumber:	this.selVeh.RegistrationNumber,
				ChassisNumber:		this.selVeh.ChassisNumber,
				VehicleId:			this.selVeh.getVehicleModelId(),
				VehicleTypeCode:	this.selVeh.VehicleTypeCode
			},
			onComplete: function(transport) //note this keyword will not work in here
			{
				Element.hide(NotifyContainer);
			}
		});
	},//end UpdateVehicleRequest
	SetVehicleDetailsRequest: function(NotifyContainer,VehId)
	{
		try
		{
			new Ajax.Updater($(this.VehDetails.Dimensions), this.url,
			{
				method: 'post',
				evalScripts: true,
				parameters:
				{
					ajaxLoad:REQUESTTYPE['GETVEHDETAILS'],
					VehicleTypeId: VehId
				},
				onComplete: function(transport) //note this keyword will not work in here
				{
					Element.hide(NotifyContainer);
				}
			});
		}
		catch (err)
		{
			alert(err);
			return false;
		}
	},//end SetVehicleDetailsRequest
	setObservableEvent: function($super,sender,args)
	{
		$super(sender);
		if (sender===this.VehDetails)
		{
			if (args.length>0)
			{
				var requestType=args[0];
				switch (requestType)
				{
					case this.ACTIONTYPE['VERIFYVEHDETAILS']:
					{
						this.MsgController.ClearServerMessageContainer();
						this.selVeh.isVerified=false;
						if (this.VerifyVehicleDetails())
						{
							this.SetVehicleFromDetails();
							this.setVehicleVerified(true);
							this.setRequest(this.REQUESTTYPE['UPDATEVEHICLE']);
							this.setRequest(this.REQUESTTYPE['SPECIALOFFER']);
						}
						else
						{
							this.MsgController.ShowLocalMsgs(this.VehDetails.ValidationErrors);
						}
						break;
					}
					case this.ACTIONTYPE['GETVEHICLEDIMENSIONS']:
					{
						this.MsgController.ClearServerMessageContainer();
						this.setRequest(this.REQUESTTYPE['GETVEHICLEDETAILS'],args[1]); //args[1] is the vehicle type id
						break;
					}
					case this.ACTIONTYPE['DRIVERCHANGE']:
					{
						this.setSelVehDriver(args[1]);
						break;
					}
				}
			}
		}//end Sender===VehDetails
		else if (sender===this.VehList)
		{
			var resvId=args[0]; //reservationId
			var rowId=args[1];
			var rowIndex=args[2];
			this.MsgController.ClearServerMessageContainer();
			if (this.VerifyVehicleDetails())
			{
				this.SetVehicleFromDetails();
				this.selVehRow=rowIndex-1;
				if (!this.isDisabled)
				{
					this.setVehicleVerified(true);
					//See note in PassengerTab.js why this is not advisable..safer to be safe
					//this.setRequest(this.REQUESTTYPE['UPDATEVEHICLE']); //Any click to another vehicle will update the vehicle
				}

				var rows=$A($(rowId).getElementsByTagName('tr')).map(Element.extend);
				var rNum=0;
				rows.each(function(r)
				{
					if (++rNum==rowIndex)
					{
						if (!r.hasClassName('highlight'))
							r.addClassName('highlight');
					}
					else
					{
						if (r.hasClassName('highlight'))
							r.removeClassName('highlight');
					}
				});
				this.SetActiveVehicle(resvId,rowIndex);
				var form=theForm; //080809 - was $('aspnetForm'); however this is too dangereous so using theForm which is set by .net automatically...in this way form name can be anything we want..Expedia and Normal booking have different form names
				var rg=form.getInputs('radio','vehResv');
				if (this.selVehRow>-1)
				{
					rg[this.selVehRow].checked=true;
					rg[this.selVehRow].activate();
				}
			}
			else
			{
					//put the radio button back where it was, cld be a simpler way to do this..no time to fnd out
				var form=theForm; //080809 - was $('aspnetForm'); however this is too dangereous so using theForm which is set by .net automatically...in this way form name can be anything we want..Expedia and Normal booking have different form names
				var rg=form.getInputs('radio','vehResv');
				if (this.selVehRow>-1)
				{
					rg[this.selVehRow].checked=true;
					rg[this.selVehRow].activate();
				}
				this.MsgController.ShowLocalMsgs(this.VehDetails.ValidationErrors);
				return false;
			}
		}//end sender=VehList
		else if (sender===this.ButtonColl)
		{
			switch (args[0])
			{
				case (TabMovDir['FWD']):
				{
					this.DisableControls();
					this.TabMapper.ConfirmationTab.setAndInitFaresTable(this.VehList.getBookingId());
					this.ButtonColl.MoveToTab(TabMovDir['FWD']);
					break;
				}
				case (TabMovDir['BCK']):
				{
					this.TabMapper.PassengersTab.EnableControls();
					this.ButtonColl.MoveToTab(TabMovDir['BCK']);
					this.resetControls(false);
					this.TabMapper.PassengersTab.ButtonColl.enableButtons(); //all need to be enabled
					break;
				}
			}//end switch
		}//end sender==this.ButtonColl
	},//end setObservableEvent
	SetVehicleFromDetails: function()
	{
		this.selVeh.RegistrationNumber=this.VehDetails.getRegistrationNumber();
		this.selVeh.ChassisNumber=this.VehDetails.getChassisNumber();
		this.selVeh.VehicleModelId=this.VehDetails.getVehModelId();
		this.selVeh.Driver=this.VehDetails.getDriver(this.DriversCollection);
	},//end SetVehicleFromDetails
	VerifyVehicleDetails: function()
	{
		var blnTest=true;
		var numErrors=0;
		this.VehDetails.ValidationErrors=new Array();//Clear it out
		if (this.VehDetails.getRegistrationNumber().length < 1)
		{
			this.VehDetails.ValidationErrors[numErrors++]=this.MESSAGES['RegistrationNumberMissing'];
			blnTest=false;
		}
		if (this.VehDetails.getRegistrationNumber().length > 30)
		{
			this.VehDetails.ValidationErrors[numErrors++]=this.MESSAGES['RegistrationNumberTooLong'];
			blnTest=false;
		}
		if (this.VehDetails.getChassisNumber().length < 1)
		{
			this.VehDetails.ValidationErrors[numErrors++]=this.MESSAGES['ChassisNumberMissing'];
			blnTest=false;
		}
		if (this.VehDetails.getChassisNumber().length > 30)
		{
			this.VehDetails.ValidationErrors[numErrors++]=this.MESSAGES['ChassisNumberTooLong'];
			blnTest=false;
		}
		if (this.VehDetails.getDriverResverationId() < 1)//its actually an index check
		{
			this.VehDetails.ValidationErrors[numErrors++]=this.MESSAGES['NoDriverSelected'];
			blnTest=false;
		}
		if (this.VehDetails.getVehModelId() < 1)
		{
			this.VehDetails.ValidationErrors[numErrors++]=this.MESSAGES['NoVehicleModelSelected'];
			blnTest=false;
		}
		return blnTest;
	},//end VerifyVehicleDetails
	DisableControls: function()
	{
		this.VehDetails.disableControls();
		this.isDisabled=true;
	},
	EnableControls: function()
	{
		this.VehDetails.enableControls();
		this.isDisabled=false;
	}
});//end VehiclesController Class

var VehicleDetails=Class.create(ReservationDetails,
{
	initialize: function($super,ControlHierarchy,Controls,DimensionText)
	{
		$super(ControlHierarchy,Controls);
		this.DimensionText=DimensionText;
		this.VehTypesIndexMap=null;
	},//end initialize
	resetControls: function()
	{
		this.setRegistrationNumber('');
		this.setChassisNumber('');
		this.setDriver(0);
		this.setVehModel(0);
		this.setDimensions(''); //clears it out
	},//end resetControls - 080802 - [DA]
	SetVehicle: function(aVeh)
	{
		this.setTitle(aVeh.ReservationId);
		this.SetVehicleModels(this.observer.VehicleTypes.get(aVeh.VehicleTypeCode));
		if (!aVeh.clickedOnce)
		{
			this.resetControls();
		}
		else
		{
			this.setRegistrationNumber(aVeh.RegistrationNumber);
			this.setChassisNumber(aVeh.ChassisNumber);
			if (aVeh.Driver!=null)
				this.setDriver(aVeh.Driver.comboIndex);
			else
				this.setDriver(0);
			this.setVehModel(aVeh.getVehicleModelId());
			this.setVehicleDimensions();
		}
	}, //end SetVehicle
	RaiseVerifyEvent: function()
	{
		try
		{
			this.observer.setObservableEvent(this,[this.observer.ACTIONTYPE['VERIFYVEHDETAILS']]);
		}
		catch (err)
		{
			alert(err);
		}
		return false;
	}, //end RaiseVerifyEvent
	RaiseVehModelChangeEvent: function()
	{
		try
		{
			this.setVehicleDimensions();
		}
		catch (err)
		{
			alert(err);
		}
		return false;
	},//end RaiseVehModelChangeEvent
	RaiseDriverChangeEvent: function()
	{
		try
		{
			this.observer.setObservableEvent(this,[this.observer.ACTIONTYPE['DRIVERCHANGE'],this.getDriverSelectedIndex()]);
		}
		catch (err)
		{
			alert(err);
		}
		return false;
	},//end RaiseDriverChangeEvent
	SetVehicleModels: function(vehTypesColl)
	{
		vehTypesColl.setOptions(this.VehModel);
		this.setVehType(vehTypesColl.getLabelText());
		this.vehTypesIndexMap=vehTypesColl.comboIndex;
	},//end SetVehicleModels
	SetDrivers: function(DriversColl)
	{
		try
		{
			clearSelectButTitle(this.Driver);
			DriversColl.drivers.each(function(drv)
			{
				var driver=drv.value;
				AddToCombo($(this.Driver),driver.comboIndex,driver.getAsComboOpt())
			},this);
		}
		catch (err)
		{
			alert(err);
		}
	}, //end setDrivers
	setRegistrationNumber: function(str)
	{
		$(this.RegistrationNumber).value=str.toUpperCase(); //style sheet is taking care of this but need it in db
	},//end setRegistrationNumber
	getRegistrationNumber: function()
	{
		return $F(this.RegistrationNumber).toUpperCase();
	},//end getRegistrationNumber
	setChassisNumber: function(str)
	{
		$(this.ChassisNumber).value=str.toUpperCase();
	},//end setChassisNumber
	getChassisNumber: function()
	{
		if ($F(this.ChassisNumber).length <1)
			this.setChassisNumber('N/A'); //client request
		return $F(this.ChassisNumber).toUpperCase();
	},//end getChassisNumber
	getDriverResverationId: function()
	{
		return $F(this.Driver); //Will always be the pass resv number
	},//end getDriverResverationId
	getDriver: function(DriverCollection)
	{
		//var idx=$(this.Driver).selectedIndex;
		return DriverCollection.getDriver(this.getDriverSelectedIndex());
	},//end getDriver
	getDriverSelectedIndex: function()
	{
		return this.Driver.selectedIndex;
	},
	setDriver: function(idx)
	{
		$(this.Driver).selectedIndex=idx;
	},//end setDriver
	getVehModelId: function()
	{
		return $F(this.VehModel); //Will always be the number
	},//end getVehModelId
	setVehModel: function(vehId)
	{
		var idx=0;
		if (this.vehTypesIndexMap!=null) //this check due to resetControls
			idx=this.vehTypesIndexMap[vehId];
		$(this.VehModel).selectedIndex=idx;
	},//end setVehModel
	setVehType: function(val)
	{
		$(this.VehType).innerHTML=val;
	},//end setVehType
	getVehType: function()
	{
		return $(this.VehType).innerHTML;
	},//end getVehType
	setVehicleDimensions: function()
	{
		var VehicleTypeId=this.getVehModelId();
		this.setDimensions(""); //clear out the text
		if (VehicleTypeId>0)
		{
			if (this.observer.Vehicles.Contains(VehicleTypeId)) //This avoids an extra ajax call, if loaded just use it :)
				this.setVehicleDimensionText(VehicleTypeId);
			else
				this.observer.setObservableEvent(this,[this.observer.ACTIONTYPE['GETVEHICLEDIMENSIONS'],VehicleTypeId]);
		}
	},//end setVehicleDimensions
	setVehicleDimensionText: function(VehId)
	{
		var aVehicle=this.observer.Vehicles.getVehicle(VehId);
		var vehText=aVehicle.getDimensionsText(this.DimensionText);
		var vehAltText=vehText.replace(/<br\/>/g," "); //removes the <br/> tags g=global replace
		var cap=aVehicle.Description;
		var overlib="return overlib(\'"+vehText+"\',CAPTION,\'"+cap+"\',RIGHT);";
		var htmlImg="<img src=\"../../images/icons/help16.gif\" onmouseover=\""+overlib+"\" onmouseout=\"nd();\" align=\"absbottom\" alt=\""+vehAltText+"\" />";
		this.setDimensions(htmlImg);
	},//end setVehicleDimensionText
	setDimensions: function(val)
	{
		$(this.Dimensions).innerHTML=val;
	}//end setDimensions
});//end VehicleDetails Class

var VehicleTypes=Class.create(
{
	initialize: function(TypeCode,VehicleMap,TypeDescription)
	{
		this.TypeCode=TypeCode;
		this.Vehicles=VehicleMap; //A hash map of items option value: option text
		this.labelText=TypeDescription;
		this.comboIndex=$H({0:0}); //first item has no key
	},//end initialize
	getLabelText: function()
	{
		return this.labelText;
	},//end getLabelText
	setLabelText: function(str)
	{
		this.labelText=str;
	},//end setLabelText
	setOptions: function(objSelect)
	{
		clearSelectButTitle($(objSelect));
		//note the method below is liable to be slow due to lexical closures - see prototype api pg 24
		var sel=$(objSelect); //grab a ref to the combo since it won't work inside each - this might have changed!
		var idx=0;
		var comboIndex=this.comboIndex;
		this.Vehicles.each(function(aVeh)
		{
			idx++;
			sel.options.add(new Option(aVeh.value,aVeh.key));
			comboIndex[aVeh.key]=idx;
		});
		this.comboIndex=comboIndex;
	}//end setOptions
});//End VehicleTypes Class

var Vehicles=Class.create(
{
	initialize: function()
	{
		this.Items=new Hash(); //this is dynamic being built up by the user choices
	},
	AddVehicle: function(Vehicle)
	{
		this.Items.set(Vehicle.Id,Vehicle);
	},
	Contains: function(VehicleId)
	{
		return !(typeof(this.getVehicle(VehicleId))=='undefined'); //NOTE: Negation ! - thus returns true if typeof is NOT undefined
	},
	getVehicle: function(VehicleId)
	{
		return this.Items.get(VehicleId);
	}
});//end Vehicles Class

//Represents an individual Vehicle
var Vehicle=Class.create(
{
    initialize: function(Map)
    {
		this.setProperties(Map);
		this.Map=Map;
    },//end initialize
    setProperties: function(Map)
    {
    	Map.each(function(property)
    	{
    		this[property.key]=property.value;
    	},this);
    },//end setProperties
    getDimensionsText: function(templateText)
    {
        var strDim=templateText;
        strDim=strDim.replace(/\{0\}/,this.Length + "M.<br/>");
        strDim=strDim.replace(/\{1\}/,this.Wdth + "M.<br/> ");
        strDim=strDim.replace(/\{2\}/,this.Hght + "M.<br/>");
        strDim=strDim.replace(/\{3\}/,this.MaxLoad + "Kg.");
        return strDim;
    },//end getDimensionsText
    inspect:function()
    {
    	var str="Vehicle\n"
    	this.Map.each(function(property)
    	{
    		str +=property.key + ':' + this[property.key];
    		str +="\n"
    	},this);
    	return str;
    }//end inspect
});//end Vehicle Class

var VehicleReservationCollection=Class.create(
{
	initialize: function()
	{
		this.VehicleReservations=new Hash(); //this is dynamic being built up by the user choices
		this.iniReservations=new Hash();
	},
	getReservation: function(ReservationId)
	{
		return this.VehicleReservations.get(ReservationId);
	},
	getFirstReservation: function()
	{
		return this.VehicleReservations.get(this.VehicleReservations.keys().first());
	},
	getNumReservations: function()
	{
		return this.VehicleReservations.size();
	},
	getIniReservations: function()
	{
		return this.iniReservations;
	},
/*	resetToIni: function()
	{
		this.set
	},*/
	setReservations: function(Reservations)
	{
		//alert(this.iniReservations.inspect());
		Reservations.each(function(v)
		{
			var vh=Object.clone(v.value);
			this.iniReservations.set(v.key,vh);
		},this);
		this.VehicleReservations=Reservations;
	},
	getReservations: function()
	{
		return this.VehicleReservations;
	}
});//end VehicleReservationCollection Class

//Reservation Super class - implement later!!
var Reservation=Class.create(
{
	initialize: function(Map)
	{
		this.setProperties(Map);
	},
	setProperties: function(Map)
	{
		Map.each(function(property)
		{
			this[property.key]=property.value;
		},this);
	}
});//end Reservation Class

var VehicleReservation=Class.create(
{
	initialize: function(Map)
	{
		Map.each(function(i)
		{
			this[i.key]=i.value;
		},this);

		this.clickedOnce=false;
		this.vehModel=null; //this will be an object
		this.isSaved=false;
		this.fare=null;
		this.hasTrailer=false; //if it has a trailer then e need to create it accordingly //TRAILERS NOT APPLIED YET
		this.trailer=null; //also an an object this time another vehicle object with its own vehModel
		this.Driver=null; //this will be an object
		this.VehicleModelId=0;
	},//end initialize
	getRadioAndImageHTML: function(rowNum,isSelected,objRef)
	{
		var id="vehResv" + (rowNum + 1);
		var str ="<label for=\"" + id + "\">"
		str +="<img align=\"absbottom\" src=\"../../images/icons/transport/carX16.png\" width=\"11\" height=\"16\" alt=\"Vehicle Icon\" />";
		str +="</label>";
		str +="<input id=\""+ id + "\" type=\"radio\" value=\"" + this.ReservationId + "\" name=\"vehResv\" onclick=\"" + objRef + ".RaiseItemSelected(this," + (rowNum+1) + ")\" style=\"border: none;\""
		if (isSelected)
			str +=" checked=\"checked\""
		str +="/>"
		return str;
	},//end getRadioAndImageHTML
	getNameHTML: function(rowNum)
	{
		var id="vehResv" + (rowNum + 1);
		var str ="<label for=\"" + id + "\">"
		str +=this.RegistrationNumber;
		str +="</label>";
		return str;
	},//end getNameHTML
	getReservationIdHTML: function(rowNum)
	{
		var id="vehResv" + (rowNum + 1);
		var str ="<label for=\"" + id + "\">"
		str +=this.ReservationId;
		str +="</label>";
		return str;
	},//getReservationIdHTML
	getFareResvNumHTML: function() //reservation number cell in fares table
	{
		var str ="<label>"
		str+=this.ReservationId; //label does not need id as non selectable
		str+="</label>";
		return str;
	},//end getFareResvNumHTML
	getFareDetailsHTML: function(text)
	{
		var str ="<label id=\"FareName\">"
		str+=this.RegistrationNumber;
		str+="</label>";
		return str;
	},//end getFareDetailsHTML
	getVehicleModelId: function()
	{
		return this.VehicleModelId;
	}//end getVehicleModelId
});//end VehicleReservation Class

var DriverCollection=Class.create(
{
	initialize: function(DriversMap)
	{
		this.drivers=DriversMap;
	},//end initialize
	getNumDrivers: function()
	{
		return this.drivers.keys().length;
	},//end getNumDrivers
	isDriverAssigned: function(key)
	{
		var blnTest=false;
		if (key>0)
		{
			var drv=this.drivers.get(key);
			if (drv.carResvNumber!=0)
				blnTest=true;
		}
		return blnTest;
	},//end isDriverAssigned
	getDriver: function(idx)
	{
		return this.drivers.get(idx);
	}//end getDriver
});//End Class DriverCollection Class

var Driver=Class.create(
{
	initialize: function(idx,fullName,passResvNum)
	{
		this.fullName=fullName;
		this.passResvNumber=passResvNum;
		this.carResvNumber=0; //Until its selected its 0
		this.comboIndex=idx;
	},//end initialize
	setCarResvNumber: function(resNum)
	{
		this.carResvNumber=resNum;
	},//end setCarResvNumber
	getAsComboOpt: function()
	{
		var opt=new Option(this.fullName,this.passResvNumber);
		return opt;
	},//end getAsComboOpt
	inspect: function()
	{
		return 'Index:'+this.comboIndex + ' Name:' + this.fullName + ' Resv Num:' + this.passResvNumber + ' Car Resv Num:' + this.carResvNumber;
	}//end inspect
});//end Driver Class

//Special Offer
var SpecialOffers=Class.create(
{
	initialize: function(OfferId,OfferRate,OfferDescription,OfferLink,OfferNotice,OfferFareBasis,OfferEntitlement,VehicleOfferRate,VehicleOfferFareBasis,VehicleOfferEntitlement)
	{
		this.OfferId=0;
		this.OfferRate=0;
		this.OfferDescription='No Special Offer';
		this.OfferLink='http://localhost/VirtuWeb/pages/E/specialoffers.aspx';
		this.OfferNotice='Click here to read the Special Offer Conditions.';
		this.OfferFareBasis='';
		this.OfferEntitlement=0;
		this.VehicleOfferRate=0;
		this.VehicleOfferFareBasis='';
		this.VehicleOfferEntitlement;
	}//end initialize
});//end SpecialOffe</>r