var locationControlsStorage = [];

//This variable using in date controls auto-filling.
var UP_ROUNDING_MODE = 'UP_ROUNDING_MODE';
var DOWN_ROUNDING_MODE = 'DOWN_ROUNDING_MODE';
var AUTO_FILLING_RANGE = 1;
var isDepartureDateAutoFilling = false;
var isReturnDateAutoFilling = false;
var isContolsLocked = false;
var LOCK_TIMEOUT = 30000;
var lastLockTime = 0;
var selectedLocations = [];

var isValidationRequired = true;

/**
 *
 * UI section of util-methods for working with HTML.
 *
 */

controls = {
	lock : function()
	{
		isContolsLocked = true;
		lastLockTime = (new Date()).getTime();
		setTimeout(this.unlock, LOCK_TIMEOUT);
	},

	unlock : function()
	{
		if ((new Date()).getTime() - lastLockTime <=  LOCK_TIMEOUT + 100)
		{
			isContolsLocked = false;
		}
	},

	isLocked : function()
	{
		return isContolsLocked;
	},

	checkAndLock : function()
	{
		if (!isContolsLocked)
		{
			this.lock();
			return true;
		}
		return false;
	}
}

objectSwapping = {

params : null,
fun : null,

swap : function(obj, fun, params, isCircular, isAllow, isInline)
{
	if (isNotDefined(isInline))
	{
		isInline = true;
	}

	if (isNotDefined(isAllow))
	{
		isAllow = true;
	}

	if (isNotDefined(isCircular))
	{
		isCircular = false;
	}

	if (!isAllow || isNotDefined(obj))
	{
		return false;
	}

	var objs = document.getElementsByName(obj.name);
	var objNewInd = -1;

	for (var i = 0; i < objs.length; i++)
	{
		if (objs[i] == obj)
		{
			if (i == objs.length - 1)
			{
				if (!isCircular)
				{
					objNewInd = i;
				}
				else
				{
					objNewInd = 0;
				}
			}
			else
			{
				objNewInd = i + 1;
			}
		}

		if (i != objNewInd)
		{
			objs[i].style.display = 'none';
		}
	}

	objs[objNewInd].style.display = isInline ? 'inline' : 'block';

	if (!isNotDefined(fun))
	{
		this.params = params;
		this.fun = fun;
		setTimeout(this.execute, 100);
	}

	return true;
},

execute : function()
{
	var fun = objectSwapping.fun;
	if (!isNotDefined(fun))
	{
		var params = objectSwapping.params;
		if (!isNotDefined(params))
		{
			fun(params[0], params[1], params[2], params[3])
		}
		else
		{
			fun();
		}
	}
}}

function changeDateOfWeek(dayPropertyId, monthAndYearPropertyId, roundingMode)
{
	var day = getElementById(dayPropertyId).value;
	var monthAndYear = getElementById(monthAndYearPropertyId).value;
	var month = monthAndYear.substr(0, monthAndYear.indexOf("-"));
	var year = monthAndYear.substring(monthAndYear.indexOf("-") + 1, monthAndYear.length);
	changeDateOfWeekByDateControlsValues(day, month, year, monthAndYearPropertyId + 'DayOfWeek');
}


/*
 * Extract value of date control like <code>Date</code> object.
 *
 * @param dayControlId : {String} Id of day control
 * @param monthYearControlId : {String} Id of monthYear control
 * @param dateFormat : {String}  The date format, default value: Date.patterns.MonthYear
 *
 * @return {Date} Controls value.
 */
function getDateControlValue(dayControlId, monthYearControlId, roundingMode)
{
	var dayControlValue = Ext.get(dayControlId).getValue();
	var monthYearControlValue = Ext.get(monthYearControlId).getValue();
	var resultDate = Date.parseDate("1-" + monthYearControlValue, Date.patterns.DayMonthYear);

	var dayValue = dayControlValue;
	var maxDayInMonth = resultDate.getDaysInMonth();
	if (maxDayInMonth < dayControlValue)
	{
		if (UP_ROUNDING_MODE == roundingMode)
		{
			dayValue = 1;
			resultDate = resultDate.add(Date.MONTH, 1);
		}
		else if (DOWN_ROUNDING_MODE == roundingMode)
		{
			dayValue = maxDayInMonth;
		}
	}
	resultDate.setDate(dayValue);
	return resultDate;
}

/*
 * Set value to date control
 *
 * @param dayControlId : {String} Id of day control
 * @param monthYearControlId : {String} Id of monthYear control
 * @param dateFormat : {String}  The date format, default value: Date.patterns.MonthYear
 * @param date : {Date} Date which set to date control
 */
function setDateControlValue(dayControlId, monthYearControlId, date)
{
	var dayControl = Ext.get(dayControlId);
	var monthYearControl = Ext.get(monthYearControlId);

	var dateControlMinValue = Date.parseDate("1-" + monthYearControl.dom.options[0].value, Date.patterns.DayMonthYear);
	dateControlMinValue.setDate(dayControl.dom.options[0].value);

	var dateControlMaxValue = Date.parseDate("1-" + monthYearControl.dom.options[monthYearControl.dom.options.length - 1].value, Date.patterns.DayMonthYear);
	dateControlMaxValue.setDate(dayControl.dom.options[dayControl.dom.options.length - 1].value);

	if (date.getTime() < dateControlMinValue.getTime())
	{
		date = dateControlMinValue;
	}
	else if (dateControlMaxValue.getTime() < date.getTime())
	{
		date = dateControlMaxValue;
	}

	var dayControlValue = date.getDate();
	for (var i = 0; i < dayControl.dom.options.length; i++)
	{
		if (dayControlValue == dayControl.dom.options[i].value)
		{
			dayControl.dom.selectedIndex = i;
			break;
		}
	}

	var monthYearControlValue = ( 1 + date.getMonth()) + "-" + date.getFullYear();
	for (var i = 0; i < monthYearControl.dom.options.length; i++)
	{
		if (monthYearControlValue == monthYearControl.dom.options[i].value)
		{
			monthYearControl.dom.selectedIndex = i;
			break;
		}
	}
}

function changeDateOfWeekByDateControlsValues(day, month, year, dayOfWeekHolderId)
{
	var dt = new Date(month + '/' + day + '/' + year);
	setInnerHtmlByID(dayOfWeekHolderId, "<p>" + dt.format('l') + "</p>");
}

function getElementById(id)
{
    return document.getElementById(id);
}

function getInnerHtmlByID(id)
{
    var element = getElementById(id);
    if (element)
    {
        return element.innerHTML;
    }
    return "";
}

function setInnerHtmlByID(id, value)
{
    var element = getElementById(id);
    if (element)
    {
        element.innerHTML = value + "";
    }
}

function showHideDivById(id, showStyle)
{
    if (showStyle == undefined)
    {
        showStyle = 'inline';
    }

    var div = getElementById(id);

    var state = div.style.display;

    div.style.display = (state == 'none') ? showStyle : 'none';
}

/**
 *
 * Text section of util-methods for working with text.
 *
 */

function isNotDefined(par)
{
	if (par == null || par == undefined)
	{
		return true;
	}
	else
	{
		return false;
	}
}

function isEmpty(str)
{
	if (isNotDefined(str) || str == '')
	{
		return true;
	}
	else
	{
		return false;
	}
}

function dayOfWeek(day, month, year)
{
	var dt = new Date(month + '/' + day + '/' + year);
	return dt.format('l');
}

/**
 *
 * Uncategoried section of util-methods.
 *
 */
function bindUnLoadEvent()
{
	try {
		window.attachEvent("onunload", invalidateSession);
	} catch (e) {
	}
}

function invalidateSession()
{
	if (screenTop > 9999){
		Ext.Ajax.request({url: 'FinishSession.do', success: void(0), failure: void(0)});
	}
}

var UrlBuilder = {
  url: ''
  ,
  paramsSize: 0
  ,
  create: function(originUrl) {
    this.url = originUrl;
    this.paramsSize = 0;
    return this;
  }
  ,
  add: function(n,v) {
    if (n == '')
      return this;
    var d = (this.paramsSize == 0) ? '?' : '&';
    this.url += d + n + '=' + v;
    this.paramsSize++;
    return this;
  }
  ,
  get: function() {
    return this.url;
  }
}

var StringUtils = {
  contains: function(s, what) {
    if (this.isEmpty(s)) {
      return false;
    } else {
      return s.indexOf(what) >= 0;
    }
  }
  ,
  isEmpty: function(s) {
    return (s == null || s.length == 0);
  }
  ,
  isNotEmpty: function(s) {
    return !this.isEmpty(s);
  }
  ,
  replace: function(s, repl, to, max) {
    if (s == null || this.isEmpty(repl) || to == null || max == 0) {
      return s;
    }
    var buf = '';
    var start = 0;
    for (var end = 0; (end = s.indexOf(repl, start)) != -1;) {
      buf += (s.substring(start, end) + to);
      start = end + repl.length;
      if (--max == 0) break;
    }
    buf += s.substring(start);
    return buf;
  }
  ,
  remove: function(s, what) {
    if (this.isEmpty(s) || this.isEmpty(what)) {
      return s;
    } else {
      return this.replace(s, what, '', -1);
    }
  }
  ,
  trim: function(s) {
    if (this.isEmpty(s)) {
      return '';
    }
    var l = 0; var r = s.length - 1;
    while (l < s.length && (s[l] == ' ' || s[l] == '\n' || s[l] == '\t')) {
      l++;
    }
    while (r > l && (s[r] == ' ' || s[r] == '\n' || s[l] == '\t')) {
      r-=1;
    }
    return s.substring(l, r + 1);
  }
}

function isValidAjaxResponse(responseText) {
  controls.unlock();
  if (StringUtils.isNotEmpty(responseText)) {
    if (StringUtils.contains(responseText, '@@@SUCCESSFUL_RESPONSE@@@')) {
      return true;
    }
  }
  return false;
}


function isAjaxSessionExpired(responseText) {
  controls.unlock();
  if (StringUtils.isNotEmpty(responseText)) {
    if (StringUtils.contains(responseText, '@@@SESSION_EXPIRED@@@')) {
      return true;
    }
  }
  return false;
}

function forwardSessionExpired() {
	document.location = "./tdpSessionExpiredError.jsp"
}

function hideErrorWarningBox() {
	var box = getElementById('glbErrorPanel');
	if (box != null) {
		box.style.display = 'none';
	}
}

function validateLocation(locationControlId, validationOnEmptyRequired, locationCodeLength, locationMaxLengthMessages, locationInvalidMessages, locationRequiredMessages, suffix)
{
	var msg = null;
	var messageKey = null;
	var result = true;
	var locationBlock = Ext.get(locationControlId + 'Block' + ((suffix) ? suffix : ''));
	var msgs = locationBlock.query(".glbErrorText");
	for(var i=0; i<msgs.length; i++)
	{
    	Ext.get(msgs[i]).remove();
  	}
  	var locationTextControlValue = Ext.get(locationControlId + 'Text').dom.value;
 	if((locationTextControlValue != "" && Ext.get(locationControlId).dom.value == ""))
	{
		if (locationTextControlValue.length < locationCodeLength)
		{
			msg = locationMaxLengthMessages[locationControlId];
			messageKey = locationMaxLengthMessages[locationControlId + 'Key'];
		}
		else
		{
			msg = locationInvalidMessages[locationControlId];
			messageKey = locationInvalidMessages[locationControlId + 'Key'];
		}
	}
	else if(locationTextControlValue == "" && validationOnEmptyRequired)
	{
		msg = locationRequiredMessages[locationControlId];
		messageKey = locationRequiredMessages[locationControlId + 'Key'];
	}
	if(msg != null)
	{
		locationBlock.dom.className = "glbErrorHilight";
		locationBlock.insertHtml('afterBegin','<p class="glbErrorText">' + msg + '</p>');

		if (messageKey != null) {
			try {
			dcsMultiTrack('DCS.dcsuri','/errors/' + messageKey,'WT.ti',msg,'DCSext.UI_Error',messageKey,'DCSext.error_location',request_uri,'WT.cg_s',cg_s,'WT.si_x','','WT.si_n','');
			} catch(e) {}
		}

		result = false;
	}
	else
	{
		locationBlock.dom.className = "";
	}
	return result;
}

/** Validate date controls. */
function validateDateControls(dayId, monthYearId, timeId, blockId, range)
{
	var dateBlock = Ext.get(blockId);
	if (blockId)
	{
		var msgs = dateBlock.query('.glbErrorText');
		for(var i=0; i<msgs.length; i++)
		{
	    	Ext.get(msgs[i]).remove();
	  	}

		if (validateDateRange(dayId, monthYearId, timeId, range))
		{
			dateBlock.dom.className = '';
			return true;
		}
		else
		{
			msg = getDateErrorMessage(monthYearId);
			dateBlock.dom.className = 'glbErrorHilight';
			dateBlock.insertHtml('afterBegin','<p class="glbErrorText">' + msg + '</p>');
			return false;
		}
	}
}

function validateDateRange(dayId, monthYearId, timeId, range)
{
	var day = getElementById(dayId).value;
	var monthYear = getElementById(monthYearId).value;

	var time = '2359';
	if (timeId)
	{
		var timeVal = getElementById(timeId).value;
		if (timeVal != 'A')
		{
			time = UIConfig[timeVal];
		}
	}
	var dt = Date.parseDate(day + '-' + monthYear + '-' + time, Date.patterns.DayMonthYear + '-Hi');
	var currentDt = new Date();
	var minDt = currentDt.add(Date.HOUR, range.min);
	if (!timeId)
	{
		currentDt.setMilliseconds(999);
		currentDt.setSeconds(59);
		currentDt.setMinutes(59);
		currentDt.setHours(23);
	}
	var maxDt = currentDt.add(Date.HOUR, range.max);

	if (dt.getTime() >= minDt.getTime() && dt.getTime() <= maxDt.getTime())
	{
		return true;
	}
	return false;
}

//Two duplicated functions fo compatibility with safari 2.x
function _validateDateControls(dayId, monthYearId, timeId, blockId, range)
{
	var dateBlock = Ext.get(blockId);
	if (blockId)
	{
		var msgs = dateBlock.query('.glbErrorText');
		for(var i=0; i<msgs.length; i++)
		{
	    	Ext.get(msgs[i]).remove();
	  	}

		if (_validateDateRange(dayId, monthYearId, timeId, range))
		{
			dateBlock.dom.className = '';
			return true;
		}
		else
		{
			var msg = getDateErrorMessage(monthYearId);
			dateBlock.dom.className = 'glbErrorHilight';
			dateBlock.insertHtml('afterBegin','<p class="glbErrorText">' + msg + '</p>');

			try {
			var errorKey = getDateErrorMessageKey(monthYearId);
			dcsMultiTrack('DCS.dcsuri','/errors/' + errorKey,'WT.ti',msg,'DCSext.UI_Error',errorKey,'DCSext.error_location',request_uri,'WT.cg_s',cg_s,'WT.si_x','','WT.si_n','');
			} catch(e) {}

			return false;
		}
	}
}

function _validateDateRange(dayId, monthYearId, timeId, range)
{
	var day = getElementById(dayId).value;
	var monthYear = getElementById(monthYearId).value;

	var separateChar = monthYear.indexOf('-');

	var parsedDate = new Date();
    parsedDate.setDate(day);
    parsedDate.setMonth(monthYear.substring(0, separateChar) - 1);
    parsedDate.setYear(monthYear.substring(separateChar + 1,  monthYear.length));

	parsedDate.setSeconds(0);

	var minutes = 59;
	var hours = 23;
	if (timeId)
	{
		var timeVal = getElementById(timeId).value;
		if (timeVal != 'A')
		{
			var time = UIConfig[timeVal];
			minutes = time.substring(2, 4);
			hours = time.substring(0, 2);
		}
	}
	parsedDate.setHours(hours);
	parsedDate.setMinutes(minutes);

	var dt = parsedDate.getTime();

	var currentDt = (new Date()).getTime();
	var minDt = currentDt + range.min;
	var maxDt = currentDt + range.max;

	if (dt >= minDt && dt <= maxDt)
	{
		return true;
	}
	return false;
}
//--- end

function correctTimeRange(obj, params)
{
	var currentInd = obj.selectedIndex;
	var secondInd = getElementById(params.secondTimeId).selectedIndex;

	if (currentInd==0 || secondInd==0) {return;}

	var secondDayInd = getElementById(params.secondDayId).selectedIndex;
	var secondMonthYearInd = getElementById(params.secondMonthYearId).selectedIndex;
	var currentDayInd = getElementById(params.currentDayId).selectedIndex;
	var currentMonthYearInd = getElementById(params.currentMonthYearId).selectedIndex;

	if ((Math.abs(secondDayInd - currentDayInd) == 1) && (secondMonthYearInd == currentMonthYearInd))
	{
		if ((params.isIncreaseSecond && (secondInd < currentInd)) || (!params.isIncreaseSecond && (secondInd > currentInd)))
		{
			getElementById(params.secondTimeId).selectedIndex = currentInd;
		}
	}
}

//don't allow to set less then AUTO_FILLING_RANGE correct day for return fields.
function autoUpReturnDateField(dayId, monthYearId)
{
	var daySel = getElementById(dayId);
	var monthYearSel = getElementById(monthYearId);
	var dt = Date.parseDate(daySel.value + '-' + monthYearSel.value, Date.patterns.DayMonthYear);
	var minDt = Date.parseDate(daySel.options[0].value + '-' + monthYearSel.options[0].value, Date.patterns.DayMonthYear);
	if (dt.getTime() < minDt.add(Date.DAY, AUTO_FILLING_RANGE).getTime())
	{
		dt = minDt.add(Date.DAY, AUTO_FILLING_RANGE);
		daySel.value = dt.format('j');
		monthYearSel.value = dt.format(Date.patterns.MonthYear);
	}
}
/** end validation of date controls. */

function updatedDublicatedFields(params)
{
	if (!isNotDefined(params) && !isNotDefined(params.origin) && !isNotDefined(params.dest))
	{
		for (var i=0; i<params.dest.length; i++)
		{
			Ext.get(params.dest[i]).dom.value = Ext.get(params.origin).dom.value;
		}
	}
}

function createLocationSearchComboBox(locationTextId, locationCodeId, locationSearchingTitle, onblurValidationRequired, baseUrl, dubs){

 var ds = new Ext.data.Store({
        proxy: new Ext.data.HttpProxy(
			new Ext.data.Connection({
				url: baseUrl,
				listeners: {
					'requestcomplete' : function(conn, resp, opts)
					{
						if (isAjaxSessionExpired(resp.responseText))
						{
							forwardSessionExpired();
						}
						else if (!isValidAjaxResponse(resp.responseText)) {
							resp.responseText = '[]';
						}
					},
					scope: this
				}
			})
		),

    reader: new Ext.data.ArrayReader({

    }, [
        {name: 'name'},
        {name: 'code'},
        {name: 'type'}
    ])
});

 var combo =  new Ext.form.ComboBox({
        store: ds,
        displayField:'name',
        typeAhead: false,
        loadingText: locationSearchingTitle,
  slistWidth: 'auto',
  shadow: false,
        hideTrigger:true,
  applyTo: locationTextId,
  minChars: 3,
  validationDelay: 0,
  queryDelay: 10,

		tpl: new Ext.XTemplate('<table cellpadding="0" cellspacing="0" border="0" width="206px"><tpl for="."><tr><td class="x-combo-list-item">{name}</td></tr></tpl></table>'),
		itemSelector: 'td.x-combo-list-item',
        /* copied and modified keyUp functionality from Combo.js - removes predefined query delay */
        onKeyUp : function(e){
                if(this.editable !== false && !e.isSpecialKey() && this.getRawValue().trim().length >= this.minChars){
                        this.lastKey = e.getKey();
                        this.dqTask.delay(10);
                }
        },
  /* copied and modified select functionality from Combo.js - catches exception on scrollChildIntoView */
  select : function(index, scrollIntoView){
   this.selectedIndex = index;
   this.view.select(index);
   if(scrollIntoView !== false){
    var el = this.view.getNode(index);
    if(el){
     try {
      this.innerList.scrollChildIntoView(el, false);
     }
     catch (e) {}
    }
   }
  },
		listeners: {
			'expand' : function(comboBox) {
				comboBox.list.setStyle("width", "auto");
				comboBox.innerList.setStyle("width", "auto");
			},
			'blur' : {
				 fn: function() {
					updatedDublicatedFields(dubs);
					var locationTextId = locationCodeId + 'Text';
					var latestLocationText = Ext.get(locationTextId).dom.value;
					if (isEmpty(selectedLocations[locationTextId]) || (selectedLocations[locationTextId] != latestLocationText))
					{
						Ext.get(locationCodeId).dom.value = '';
						selectedLocations[locationTextId] = Ext.get(locationTextId).dom.value;
					}
				 	if(onblurValidationRequired && isValidationRequired) customValidateLocation(locationCodeId, false);
				 },
				 scope: this,
				 delay: 250
			},
			'select' : {
				fn: function() {
					updatedDublicatedFields(dubs);
					var locationTextId = locationCodeId + 'Text';
					selectedLocations[locationTextId] = Ext.get(locationTextId).dom.value;
					customValidateLocation(locationCodeId, false);
				},
				scope : this,
				delay: 100
			},
			scope: this
		},
  onSelect : function(record, index){
	  if(this.fireEvent('beforeselect', this, record, index) !== false){
      	  if (record.data['code'] == '@@@FAILURE_RESPONSE@@@')
      	  {
      	  	  this.setValue('');
	          this.collapse();
	       	  this.fireEvent('select', this, record, index);
	       	  Ext.get(locationCodeId).dom.value = '';
       	  }
       	  else
       	  {
	       	  this.setValue(record.data[this.valueField || this.displayField]);
	          this.collapse();
	       	  this.fireEvent('select', this, record, index);
	       	  Ext.get(locationCodeId).dom.value = record.data['code'];
	       	  Ext.get(locationCodeId + "Type").dom.value = record.data['type'];
       	  }
      }
  }
    });
    locationControlsStorage[locationControlsStorage.length++] = combo ;
    return combo;
}

function formatFloat(number,minFract,maxFract,decimal,thousand){
	decimal = (decimal)? decimal: ".";
	thousand = (thousand)? thousand: " ";
	var rightZero = "";
	var powered = Math.pow(10,maxFract);
	var integer = "";

	number = Math.round(number*powered)/powered;

	var arrNum = (""+number).split('.');

	if(arrNum.length<2){
		arrNum[1]="";
	}

	for(var i=arrNum[1].length; i<minFract; i++){
		rightZero += "0";
	}

	if(!(arrNum[1] || minFract)){
		decimal="";
	}

	for(var i=arrNum[0].length; i>0;){
		i-=3;
		if(i<=0){
			integer=arrNum[0].substr(0,i+3)+integer;
		}
		else{
			integer=thousand+arrNum[0].substr(i,3)+integer;
		}
	}

	return (integer+decimal+arrNum[1]+rightZero);
}

function clickLink(location)
{
	if (controls.checkAndLock() && !isNotDefined(location))
	{
		window.location.href = location;
	}
}

// Retrieve air fare rues information
function retrieveFareRules(fareId, titleName, sourceName)
{
	var popupId = 'idFlightResultsFareRulesInfo' + Math.abs(fareId);

	function airFareRulesRetrieveCallBack(response)
	{
		if (isAjaxSessionExpired(response.responseText))
		{
				forwardSessionExpired();
		}
		popupFramework.populationLazyContent({id:popupId}, response.responseText);
	}

	popupFramework.show({id: popupId, requestURL:'contentblocks/hugePopupTemplateRetrieve.jsp?titleName=' + titleName, opacity:true, templateName:'popupLarge',position:'centered'});


	if (popupFramework.lazyContentsPool[popupId] == null || popupFramework.lazyContentsPool[popupId] == undefined)
	{
		Ext.Ajax.request({
			url: 'getFareRulesInformation.do?requestSource=' + sourceName +'&selectedItinId=' + fareId,
			success: airFareRulesRetrieveCallBack
		});
	}
}

//retrieve hotel cancelation policies
function getCancelationRules(url, hotelId, titleName)
{
	var popupId = 'idHotelResultsCancellationTermsInfo' + Math.abs(hotelId);

	function hoteCancelationPoliciesRetrieveCallBack(response)
	{
		if (isAjaxSessionExpired(response.responseText))
		{
				forwardSessionExpired();
		}
		popupFramework.populationLazyContent({id:popupId}, response.responseText);
	}

	popupFramework.show({id: popupId, requestURL:'contentblocks/hugePopupTemplateRetrieve.jsp?titleName=' + titleName, opacity:true, templateName:'popupLarge',position:'centered'});

	if (popupFramework.lazyContentsPool[popupId] == null || popupFramework.lazyContentsPool[popupId] == undefined)
	{
		Ext.Ajax.request({
			url: url,
			success: hoteCancelationPoliciesRetrieveCallBack
		});
	}
}