//--------- TEST-----------

function postVersion()
{	alert ('planning functions - version : 0.1');
}

//------------- JS functions used by PLANNING -----------------

var  NO_RENT = 0;
var  LOW_SEASON = 1;
var  MID_SEASON = 2;
var  HIGH_SEASON = 3;

var  SELECTION_VALUE = 100;
var  OPTION_VALUE = 200;
var  BOOKED_VALUE = 500;

var  DAY_IS_AVAILABLE = 0;
var  ERROR_NO_PLANNING = -1;
var  ERROR_ALREADY_BOOKED = -2;
var  ERROR_NO_RENT = -3;
var  ERROR_NO_RETRO = -4;

var  previousMonthID = '194601';
var  currentMonthID = '194602';
var  nextMonthID = '194603';

var  planSeparator = ',';

var  previousMonthPlan = null;
var  currentMonthPlan = null;
var  nextMonthPlan = null;

var  savedDayStyle = null;
var  selectionPlanValue = 200;

// init with today or contract dates
var  stayStartDate = null; 
var  stayEndDate =  null; 

var  currentStartDateID = null; 
var  currentEndDateID = null; 

// prices changes
var  priceChangeDateID = null; 
var  currentPriceDateID = null; 

//var  selectedDate =  null;

//----- all days in the stay -------
var  allDaysInStay =  new Array();

// force values
var	 myProcessIsAdmin = false;

// selected apartment
var  mySelectedApartment = 'avp01';

//--- selection styles ---

var  myCustomerSelectionBG = 'rgb(222, 153, 184)';
var  myCustomerSelectionColor = 'rgb(160, 24, 87)';
var  myCustomerSelectionBorderColor = 'rgb(160, 24, 87)';

var  myCustomerAVP01SelectionBG = 'rgb(222, 153, 184)';
var  myCustomerAVP01SelectionColor = 'rgb(160, 24, 87)';
var  myCustomerAVP01SelectionBorderColor = 'rgb(160, 24, 87)';

var  myCustomerAVP02SelectionBG = 'rgb(220, 222, 221)';
var  myCustomerAVP02SelectionColor = 'rgb(69, 69, 69)';
var  myCustomerAVP02SelectionBorderColor = 'rgb(69, 69, 69)';

var  myAdminSelectionBG = 'red';
var  myAdminSelectionColor = 'white';
var  myAdminSelectionBorderColor = 'darkred';


//-----------------------  on load -------------------------

function setApartment( oneApartment) 
{	   
	mySelectedApartment =  oneApartment;
	if	 ( mySelectedApartment == 'avp01' )
		{
		   myCustomerSelectionBG = myCustomerAVP01SelectionBG;
		   myCustomerSelectionColor = myCustomerAVP01SelectionColor;
		   myCustomerSelectionBorderColor = myCustomerAVP01SelectionBorderColor;
		}
	if	 ( mySelectedApartment == 'avp02' )
		{
		   myCustomerSelectionBG = myCustomerAVP02SelectionBG;
		   myCustomerSelectionColor = myCustomerAVP02SelectionColor;
		   myCustomerSelectionBorderColor = myCustomerAVP02SelectionBorderColor;
		}
}

//-----------------------  planning options : dates or apartment-------------------------

function setPlanningApartment( oneApartment) 
{
	//alert ("Cette option sera disponible très prochainement. \nThis option will be available very shortly.");
	document.getElementById('changeApartForm').submit();
}


//-----------------------  ONE DAY processing -------------------------


function processOneDay( oneDayID) 
{		 

	//alert ('updating : ' + oneDayID);

	toDay =  new Date();
	toDay.setHours(0,0,0);
	// get date object
	selectedDateID = oneDayID;
	selectedDate = getNewDateWithFullDayID(oneDayID);
	
	//alert ('processing : ' + oneDayID + '\n' + 'translated ID : ' + getDayID(selectedDate));

	if   ( selectedDate < toDay )
		 { // no retroactivity
		   postErrorAlert (selectedDate, ERROR_NO_RETRO);
		   return;
		 }
	
	// has stay been already initialized ?
	if   ( stayStartDate == null ) 
		 { initOneStayDate('start', selectedDateID);
		   initOneStayDate('end', selectedDateID);
		   return;
		 }

	stayStartDateID = getDayID(stayStartDate);
	stayEndDateID = getDayID(stayEndDate);

	if   ( selectedDateID < stayStartDateID )
		 { // extend before current start of stay
		   extensionEnd = getNewDate(stayStartDate);
		   extensionEnd.setDate(extensionEnd.getDate() - 1);
		   extendCurrentStay(selectedDate, extensionEnd);
		   return;
		 }
	
	if   ( selectedDateID > stayEndDateID )
		 { // extend after current end of stay
		   extensionStart = getNewDate(stayEndDate);
		   extensionStart.setDate(extensionStart.getDate() + 1);
		   extendCurrentStay(extensionStart, selectedDate);
		   return;
		 }
		 
	// selected date is start of stay  : UN-select
	if   ( selectedDateID == stayStartDateID )
		 { 
		   selectedDay = getDayInStayWithID(selectedDateID);
		   selectedDay.setSelected(false);	
		   // UN-select the whole stay ?
		   // must unselect the last day (only one remains) 
		   if   ( stayStartDateID == stayEndDateID ) 
				{ // reset stay dates
				  updateStayDate('start', null);
				  updateStayDate('end', null);
				  return;
				}
		   
		   // stay still goes on : new start = old + 1
		   newStayStartDate = getNewDate(stayStartDate);
		   newStayStartDate.setDate(newStayStartDate.getDate() + 1);
		   updateStayDate('start', newStayStartDate);
		 }
	
	// selected date is end of stay  : UN-select
	if   ( selectedDateID == stayEndDateID )
		 { selectedDay = getDayInStayWithID(selectedDateID);
		   selectedDay.setSelected(false);	
		   // new end = old - 1
		   newStayEndDate = getNewDate(stayEndDate);
		   newStayEndDate.setDate(newStayEndDate.getDate() - 1);
		   updateStayDate('end', newStayEndDate);
		 }
	
	// selected date is included in current stay : no action
}

// set stayDates to be used "onload"
function setCurrentStayDatesID(oneStartDateID, oneEndDateID) 
{		 
	currentStartDateID = oneStartDateID; 
	currentEndDateID = oneEndDateID; 
}

// load current stay dates if they have been set
function loadCurrentStayDates() 
{		 
	if   ( (currentStartDateID != null) && (currentEndDateID != null))
		 {  // initial stay dates: start day both ends
			 initOneStayDate('start', currentStartDateID);
			 initOneStayDate('end', currentStartDateID);
			 // extend stay to current end
			 processOneDay( currentEndDateID);
		 }
}

/*---------------------
function initStayDates(oneStartDateID, oneEndDateID) 
{		 
	initOneStayDate('start', oneStartDateID);
	initOneStayDate('end', oneEndDateID);
}
---------------------*/

function initOneStayDate(oneType, oneStayDateID) 
{		 

	//alert ('initOneStayDate : ' + oneType + '  ' + oneStayDateID);


	oneStayDay = getDayInStayWithID(oneStayDateID);
	
	returnCode = oneStayDay.isAvailable();
	if   ( returnCode < 0 )
		 { // not available 
		   postErrorAlert (returnCode);
		   return;
		 }

	oneStayDay.setSelected(true);	
	// get date object
	oneStayDate = getNewDateWithFullDayID(oneStayDateID);
	updateStayDate(oneType, oneStayDate);
}

// add one period to current stay (before or after)
// start and end dates are included in extension
function extendCurrentStay ( oneStartDate, oneEndDate) 
{		 
/*---------------------------

	alert ( '------- extendCurrentStay : '  + '\n'
		  + 'currentStaySTART : '  + getDayID(stayStartDate)  + '\n' 
		  + 'currentStayEND : '  + getDayID(stayEndDate)  + '\n' 
		  + 'extensionStart : '  + getDayID(oneStartDate)  + '\n' 
		  + 'extensionEnd : '  + getDayID(oneEndDate) );
----------------------------*/

	oneEndDateID = getDayID(oneEndDate);
	currentDate = getNewDate(oneStartDate);
	currentDateID = getDayID(currentDate);
	
	// check availability of all days before update
	while   ( currentDateID <= oneEndDateID )
			{ 
			  currentDay = getDayInStayWithID(currentDateID);
			  returnCode = currentDay.isAvailable();
			  if   ( returnCode < 0 )
				   { // not available : no extension
				     postErrorAlert (currentDate, returnCode);
				     return;
				   }
			  // day is available, check next one.
			  currentDate.setDate(currentDate.getDate() + 1);
			  currentDateID = getDayID(currentDate);
			}// end while

	// all days are available : actual extension
	currentDate = getNewDate(oneStartDate);
	currentDateID = getDayID(currentDate);

	while   ( currentDateID <= oneEndDateID )
			{ 
			  currentDay = getDayInStayWithID(currentDateID);
			  currentDay.setSelected(true);
			  // next date
			  currentDate.setDate(currentDate.getDate() + 1);
			  currentDateID = getDayID(currentDate);
			}// end while
			
	// update stay start and end dates
	if   ( getDayID(oneStartDate) < getDayID(stayStartDate) )
		 { updateStayDate('start', oneStartDate);
		 }

	if   ( getDayID(oneEndDate) > getDayID(stayEndDate) )
		 { updateStayDate('end', oneEndDate);
		 }
	
}
//-------------------------------  handle PRICES  ------------------------

// set price change dateID from services Manager
function setPriceChangeDateID(oneChangeDateID)
{	priceChangeDateID = oneChangeDateID;
}

// post price in list for stayStartDate
function postPricesAtStartDateID()
{
	var previousPricePeriod = '';
	newStartDateID = getDayID(stayStartDate);
	if   ( currentPriceDateID != null)
		 { // determine period which prices have been posted for
		   if   ( currentPriceDateID <  priceChangeDateID ) previousPricePeriod = 'until'; 
		   else							      previousPricePeriod = 'asFrom';
		 }
	// update currentPriceDate 
	currentPriceDateID = newStartDateID;

	// 18.07.2011 : another price date, as it is used in ALL MENUS (without planning functions)
	ratesReferenceDateID = newStartDateID;

	// prices have been posted already, and may not require change
	if   (( currentPriceDateID <  priceChangeDateID ) && (previousPricePeriod == 'until')) return; 
	if   (( currentPriceDateID >= priceChangeDateID ) && (previousPricePeriod == 'asFrom')) return; 



//alert ( 'postPricesAtStartDateID : '  + newStartDateID + ' - ' + previousPricePeriod);


	// post prices for new date
	// determine priceIndex in pricesArray ( priceTagID, lowPeriod, highPeriod)
	if	( currentPriceDateID <  priceChangeDateID )	priceIndex = 1; 
	else								priceIndex = 2;
	// prices array has been built separately by ServicesHandler
	for	( j = 0; j < pricesArray.length; j++)
		{
		  currentPriceElement = pricesArray[j];
		  currentPriceTagID = currentPriceElement[0];
		  docElement = document.getElementById(currentPriceTagID);
		  if	( docElement != null )
			{ 
			docElement.innerHTML = currentPriceElement[priceIndex];
			}
		}
	
}



//-------------------------------  UTILITIES  ------------------------

//------- process days in stay --------------

function getDayInStayWithID(oneDayID) 
{	
	for ( j = 0; j < allDaysInStay.length; j++)
		{ if   ( allDaysInStay[j].myID == oneDayID ) return allDaysInStay[j];
		}

	// day does not exist : create new one
	newDay = createNewDayInStay (oneDayID);
	// register in Array
	allDaysInStay.push(newDay);
	
	return newDay;
}

function createNewDayInStay (oneDayID) 
{	
	oneNewDay = new DayInStay(oneDayID);
	// save initial style
	oneNewDay.myDocStyle = document.getElementById(oneDayID).style;
	oneNewDay.myInitialDayStyle = new DayStyle ( oneNewDay.myDocStyle['backgroundColor'],
								   oneNewDay.myDocStyle['color'], oneNewDay.myDocStyle['borderColor']);
	// set monthPlan 
	oneNewDay.myMonthPlan = getMonthPlan(oneDayID);
	// set initial PlanValue
	selectedIndex = oneDayID.substr(6,2) - 1;
	if   ( oneNewDay.myMonthPlan == null ) return ERROR_NO_PLANNING;
	oneNewDay.myInitialPlanValue = oneNewDay.myMonthPlan[selectedIndex];
	
	return oneNewDay;
}

//------- process dates --------------

function updateStayDate(oneType, oneDate)
{
	// default when $oneDate == null
	oneDayID = ''; 
	stayDayID = '';
	stayMonthID = '';
	stayYearID = '';
	oneNewDate = null;

	// $oneDate is set 
	if   (	oneDate != null )
		 {	oneDayID = getDayID(oneDate); 
			stayDayID = oneDayID.substr(6,2);
			stayMonthID = oneDayID.substr(4,2);
			stayYearID = oneDayID.substr(0,4);
			oneNewDate = getNewDate(oneDate);
		 }

	if   ( oneType == 'start')
		 { stayStartDate = oneNewDate;
		   // update form params
		   document.getElementById('stayFirstDay').value = stayDayID;
		   document.getElementById('stayFirstMonth').value = stayMonthID;
		   document.getElementById('stayFirstYear').value = stayYearID;
		   
		   // startDate is the reference to determine prices
		   // no prices for planning update by admin
		   if   ( ( stayStartDate != null ) && ( myProcessIsAdmin == false))
				    postPricesAtStartDateID();

		   // check stay boundary
		   if   ( stayStartDate != null )
				{ prevDate = getNewDate(stayStartDate);
				  prevDate.setDate(prevDate.getDate() - 1);
				  prevDateID = getDayID(prevDate);
				  //--------- 30.01.2007 --------------
				  //prevDay = getDayInStayWithID(prevDateID);
				  prevDay = new DayInStay(prevDateID);
				  // set monthPlan 
				  prevDay.myMonthPlan = getMonthPlan(prevDateID);
			      //------------------------------------
				  returnCode = prevDay.isAvailable();
				}
		   else {  returnCode = 9;
				}
		   // update previous stay hidden field
		   document.getElementById('previousStayIsBooked').value = (returnCode < 0) ? 1 : 0;
		   return;
		 }

	if   ( oneType == 'end')
		 { stayEndDate = oneNewDate;
		   // update form params
		   document.getElementById('stayLastDay').value = stayDayID;
		   document.getElementById('stayLastMonth').value = stayMonthID;
		   document.getElementById('stayLastYear').value = stayYearID;
		   // check stay boundary
		   if   ( stayEndDate != null )
				{ nextDate = getNewDate(stayEndDate);
				  nextDate.setDate(nextDate.getDate() + 1);
				  nextDateID = getDayID(nextDate);
				  //--------- 30.01.2007 --------------
				  //nextDay = getDayInStayWithID(nextDateID);
				  nextDay = new DayInStay(nextDateID);
				  // set monthPlan 
				  nextDay.myMonthPlan = getMonthPlan(nextDateID);
			      //------------------------------------
				  returnCode = nextDay.isAvailable();
				}
		   else {  returnCode = 9;
				}
		   // update previous stay hidden field
		   document.getElementById('nextStayIsBooked').value = (returnCode < 0) ? 1 : 0;
		   return;
		 }
}
		   

// clone one date
function getNewDate(oneDate) 
{		 
	oneNewDate = new Date();
	oneNewDate.setFullYear(oneDate.getFullYear(), oneDate.getMonth(), oneDate.getDate());
	oneNewDate.setHours(0,0,0);
	return oneNewDate;
}

// get new date object with YYYYMMDD
function getNewDateWithFullDayID(oneFullDayID) 
{		 
	oneDayID = oneFullDayID.substr(6,2);
	oneMonthID = oneFullDayID.substr(4,2);
	oneYearID = oneFullDayID.substr(0,4);
	
	// month starts at 0 !
	oneDate =  new Date();
	oneDate.setFullYear(oneYearID, oneMonthID-1, oneDayID);
	oneDate.setHours(0,0,0);
	
	return oneDate;
}

	
// returns YYYYMMDD
function getDayID ( oneDate) 
{		 
	dayID = oneDate.getDate().toString();
	if   (dayID.length == 1) dayID = '0' + dayID; 
	// month starts at 0 !
	month = oneDate.getMonth() + 1;
	monthID = month.toString();
	if   (monthID.length == 1) monthID = '0' + monthID; 
	oneDayID = oneDate.getFullYear().toString() + monthID + dayID;

	//alert ( 'getDayID  monthID : ' + oneDayID + '\n' + 'fullYear : ' + oneDate.getFullYear());

	return oneDayID;
}


// identify monthPlan
function getMonthPlan ( oneDayID) 
{		 
	oneMonthPlan = null;
	selectedMonthID = oneDayID.substr(0,6);
	if   ( selectedMonthID == previousMonthID ) oneMonthPlan = previousMonthPlan;
	if   ( selectedMonthID == currentMonthID )	oneMonthPlan = currentMonthPlan;
	if   ( selectedMonthID == nextMonthID )		oneMonthPlan = nextMonthPlan;
	return oneMonthPlan;
}


//-- set ID and planning for current(0), previous(-1) or next(1) month
function setMonth ( oneMonthType, oneID, onePlanString) 
{		 
	if   ( oneMonthType == -1 ) 
		 { previousMonthID = oneID;
		   previousMonthPlan = onePlanString.split(planSeparator);
		 }

	if   ( oneMonthType ==  0 ) 
		 { currentMonthID = oneID;
		   currentMonthPlan = onePlanString.split(planSeparator);
		 }

	if   ( oneMonthType ==  1 ) 
		 { nextMonthID = oneID;
		   nextMonthPlan = onePlanString.split(planSeparator);
		 }
} 

function  postErrorAlert (oneDate, oneErrorCode)
{
	oneDateString =  oneDate.getDate() + '.' 
				  +  (oneDate.getMonth() + 1) + '.' 
				  +  oneDate.getFullYear(); 
	message = 'Unknown error number : ' + oneErrorCode;
	switch  ( oneErrorCode)
			{ 
				case ERROR_NO_PLANNING :	message  = ERR_MES_NO_PLANNING;
											break;
				case ERROR_ALREADY_BOOKED : message  = ERR_MES_ALREADY_BOOKED;
											break;
				case ERROR_NO_RENT :		message  = ERR_MES_NO_RENT;
											break;
				case ERROR_NO_RETRO :		toDayString = toDay.getDate() + '.' 
														+ (toDay.getMonth() + 1) + '.' 
														+ toDay.getFullYear(); 
											message  = ERR_MES_NO_RETRO;
											message += ERR_MES_NO_RETRO_TITLE + toDayString + '\n';
											break;
			}
	
	message = oneDateString + '\n' + message;
	alert (message);
}


//--------------------------------------- CLASSES --------------------------------

function DayStyle ( oneBGColor, oneColor, oneBorderColor) 
{		 
	this.bgColor = oneBGColor;
	this.color = oneColor;
	this.borderColor = oneBorderColor;
}

//---------  single Day in the Stay ----------

function DayInStay (oneDayID) 
{		 
	this.myID = oneDayID;
	this.myInitialDayStyle = null;
	this.myDocStyle = null;
	this.myMonthPlan = null;
	this.myInitialPlanValue = null;

//-- methods --
	this.setSelected = setSelected;
	this.isAvailable = isAvailable;
}

function isAvailable() 
{		 
	//alert ('checking availability : ' + this.myID);

	// admin forces values : always available
	if   (  myProcessIsAdmin == true ) return DAY_IS_AVAILABLE;
	

	selectedMonthID = this.myID.substr(0,6);
	selectedIndex = this.myID.substr(6,2) - 1;
	
	// identify monthPlan
	if   ( this.myMonthPlan == null ) return ERROR_NO_PLANNING;
		
	dayPlanValue = this.myMonthPlan[selectedIndex];
	
	// check whether the day may be BOOKED or with OPTION (index starts with zero)
	if   ( dayPlanValue > OPTION_VALUE )
		 { return ERROR_ALREADY_BOOKED;
		 }
	
	// check whether this day is being UN-Selected by user (has been selected)
	if   ( ( dayPlanValue <= OPTION_VALUE) && ( dayPlanValue > SELECTION_VALUE) )
		 {   return DAY_IS_AVAILABLE;
		 }
	
	// check whether this day is allowed to be selected
	if   ( dayPlanValue == NO_RENT) return ERROR_NO_RENT;

	return DAY_IS_AVAILABLE;	
}

// select or UN-select one day
function  setSelected (isSelected)
{
	//alert ('updating : ' + this.myID);

	if   ( this.myMonthPlan == null ) return;
	
	// update Plan (select or UN-select)
	selectedIndex = this.myID.substr(6,2) - 1;

	// update GUI
	if   ( isSelected == false )
		 { //-- UN-Select day
		   // restore plan value
		   this.myMonthPlan[selectedIndex] = this.myInitialPlanValue;
		   //restore previous style
		   if   ( this.myInitialDayStyle != null )
				{ 
				  this.myDocStyle['backgroundColor']= this.myInitialDayStyle.bgColor;
				  this.myDocStyle['color']= this.myInitialDayStyle.color;
				  this.myDocStyle['borderColor']= this.myInitialDayStyle.borderColor;
				}
				
		   // deRegister day as start or end
		   return;
		 }

	//-- SELECT DAY--
	
	// update Plan
	this.myMonthPlan[selectedIndex] = SELECTION_VALUE + eval(this.myMonthPlan[selectedIndex]); 
	
	// set selected style

	if   (  myProcessIsAdmin == true )
		 { 
			this.myDocStyle['backgroundColor']= myAdminSelectionBG;
			this.myDocStyle['color']= myAdminSelectionColor;
			this.myDocStyle['borderColor']= myAdminSelectionBorderColor;
		 }
	else {
			this.myDocStyle['backgroundColor']= myCustomerSelectionBG;
			this.myDocStyle['color']= myCustomerSelectionColor;
			this.myDocStyle['borderColor']= myCustomerSelectionBorderColor;
		 }
	

} 


