var arrivalList = new Object();//Mapping of Terminal ID  to LIST of Terminal ID's it can goto.
var terminalMap = new Object();//Mapping of Terminal ID's and details about the terminal.
var regionList = new Array();

var defaultDepartureText="Select Departure Location";
var defaultArrivingLocation="Select Arriving Location";
var departureElementId = 'departureCombo';
var arrivalElementId = 'arrivalCombo';

function addRegions(){
	regionList.push('Mainland-Sunshine Coast');//0
	regionList.push('Vancouver Island');//1
	regionList.push('Gulf Islands');//2
	regionList.push('Mid and North Coast');//3	
}

function addTerminals(){
	terminalMap['ALF']={id: 'ALF', region: 3, name: 'Alliford Bay', location: 'Queen Charlottes'};
	terminalMap['ALR']={id: 'ALR', region: 2, name: 'Alert Bay', location: 'Cormorant Island'};
	terminalMap['BEC']={id: 'BEC', region: 3, name: 'Bella Coola', location: 'Bella Coola'};
	terminalMap['BKY']={id: 'BKY', region: 1, name: 'Buckley Bay', location: 'Buckley Bay'};
	terminalMap['BOW']={id: 'BOW', region: 2, name: 'Snug Cove', location: 'Bowen Island'};
	terminalMap['BTW']={id: 'BTW', region: 1, name: 'Brentwood Bay', location: 'Brentwood Bay'};
	terminalMap['CAM']={id: 'CAM', region: 1, name: 'Campbell River', location: 'Campbell River'};
	terminalMap['CFT']={id: 'CFT', region: 1, name: 'Crofton', location: 'Crofton'};
	terminalMap['CHM']={id: 'CHM', region: 1, name: 'Chemainus', location: 'Chemainus'};
	terminalMap['CMX']={id: 'CMX', region: 1, name: 'Little River', location: 'Comox'};
	terminalMap['COR']={id: 'COR', region: 2, name: 'Whaletown', location: 'Cortes Island'};
	terminalMap['DNE']={id: 'DNE', region: 2, name: 'Gravelly Bay', location: 'Denman Is. East'};
	terminalMap['DNM']={id: 'DNM', region: 2, name: 'Denman Is. West', location: 'Denman Is. West'};
	terminalMap['DUK']={id: 'DUK', region: 1, name: 'Duke Point', location: 'Nanaimo'};
	terminalMap['ERL']={id: 'ERL', region: 0, name: 'Earls Cove', location: 'Sechelt'};
        terminalMap['EAS']={id: 'EAS', region: 0, name: 'Eastbourne', location: 'Keats Island'};
	terminalMap['FUL']={id: 'FUL', region: 2, name: 'Fulford Harbour', location: 'Salt Spring Is.'};
	terminalMap['GAB']={id: 'GAB', region: 2, name: 'Descanso Bay', location: 'Gabriola Island'};
	terminalMap['GAM']={id: 'GAM', region: 0, name: 'New Brighton', location: 'Gambier Island'};
	terminalMap['HRB']={id: 'HRB', region: 2, name: 'Heriot Bay', location: 'Quadra East'};
	terminalMap['HRN']={id: 'HRN', region: 2, name: 'Shingle Spit', location: 'Hornby Island'};
	terminalMap['HSB']={id: 'HSB', region: 0, name: 'Horseshoe Bay', location: 'Vancouver'};
	terminalMap['KLE']={id: 'KLE', region: 3, name: 'Klemtu', location: 'Swindle Island'};
	terminalMap['KPR']={id: 'KPR', region: 2, name: 'Kuper Island', location: 'Kuper Island'};
	terminalMap['KTS']={id: 'KTS', region: 0, name: 'Keats Landing', location: 'Keats Island'};
	terminalMap['LNG']={id: 'LNG', region: 0, name: 'Langdale', location: 'Sunshine Coast'};
	terminalMap['MCN']={id: 'MCN', region: 1, name: 'Port McNeill', location: 'Port McNeill'};
	terminalMap['MIL']={id: 'MIL', region: 1, name: 'Mill Bay', location: 'Mill Bay'};
	terminalMap['NAH']={id: 'NAH', region: 1, name: 'Nanaimo Harbour', location: 'Nanaimo'};
	terminalMap['NAN']={id: 'NAN', region: 1, name: 'Departure Bay', location: 'Nanaimo'};
	terminalMap['PBB']={id: 'PBB', region: 3, name: 'McLoughlin Bay', location: 'Bella Bella'};
	terminalMap['PLH']={id: 'PLH', region: 2, name: 'Long Harbour', location: 'Salt Spring Is.'};
	terminalMap['POB']={id: 'POB', region: 2, name: 'Otter Bay', location: 'Pender Island'};
	terminalMap['POF']={id: 'POF', region: 3, name: 'Ocean Falls', location: 'Ocean Falls'};
	terminalMap['PPH']={id: 'PPH', region: 3, name: 'Bear Cove', location: 'Port Hardy'};
	terminalMap['PPR']={id: 'PPR', region: 3, name: 'Prince Rupert', location: 'Prince Rupert'};
	terminalMap['PSB']={id: 'PSB', region: 2, name: 'Sturdies Bay', location: 'Galiano Island'};
	terminalMap['PSK']={id: 'PSK', region: 3, name: 'Skidegate', location: 'Queen Charlottes'};
	terminalMap['PST']={id: 'PST', region: 2, name: 'Lyall Harbour', location: 'Saturna Island'};
	terminalMap['PVB']={id: 'PVB', region: 2, name: 'Village Bay', location: 'Mayne Island'};
	terminalMap['PWR']={id: 'PWR', region: 0, name: 'Westview', location: 'Powell River'};
	terminalMap['QDR']={id: 'QDR', region: 2, name: 'Quathiaski Cove', location: 'Quadra West'};
	terminalMap['SHW']={id: 'SHW', region: 3, name: 'Shearwater', location: 'Denny Island'};
	terminalMap['SLT']={id: 'SLT', region: 0, name: 'Saltery Bay', location: 'Powell River'};
	terminalMap['SOI']={id: 'SOI', region: 2, name: 'Sointula', location: 'Malcolm Island'};
	terminalMap['SWB']={id: 'SWB', region: 1, name: 'Swartz Bay', location: 'Victoria'};
	terminalMap['TEX']={id: 'TEX', region: 2, name: 'Blubber Bay', location: 'Texada Island'};
	terminalMap['THT']={id: 'THT', region: 2, name: 'Thetis Island', location: 'Thetis Island'};
	terminalMap['TSA']={id: 'TSA', region: 0, name: 'Tsawwassen', location: 'Vancouver'};
	terminalMap['VES']={id: 'VES', region: 2, name: 'Vesuvius Bay', location: 'Salt Spring Is.'};	
}
function addArrivals(){
	arrivalList['ALF']=['PSK'];
	arrivalList['ALR']=['MCN','SOI'];
	arrivalList['BEC']=['KLE','PBB','POF','PPH','PPR','SHW'];
	arrivalList['BKY']=['DNM'];
	arrivalList['BOW']=['HSB'];
	arrivalList['BTW']=['MIL'];
	arrivalList['CAM']=['QDR'];
	arrivalList['CFT']=['VES'];
	arrivalList['CHM']=['KPR','THT'];
	arrivalList['CMX']=['PWR'];
	arrivalList['COR']=['HRB'];
	arrivalList['DNE']=['HRN'];
	arrivalList['DNM']=['BKY'];
	arrivalList['DUK']=['TSA'];
        arrivalList['EAS']=['KTS'];
	arrivalList['ERL']=['SLT'];
	arrivalList['FUL']=['SWB'];
	arrivalList['GAB']=['NAH'];
	arrivalList['GAM']=['KTS','LNG'];
	arrivalList['HRB']=['COR'];
	arrivalList['HRN']=['DNE'];
	arrivalList['HSB']=['BOW','LNG','NAN'];
	arrivalList['KLE']=['BEC','PBB','POF','PPH','PPR','SHW'];
	arrivalList['KPR']=['CHM','THT'];
	arrivalList['KTS']=['GAM','EAS','LNG'];
	arrivalList['LNG']=['GAM','HSB','KTS'];
	arrivalList['MCN']=['ALR','SOI'];
	arrivalList['MIL']=['BTW'];
	arrivalList['NAH']=['GAB'];
	arrivalList['NAN']=['HSB'];
	arrivalList['PBB']=['BEC','KLE','POF','PPH','PPR','SHW'];
	arrivalList['PLH']=['POB','PSB','PST','PVB','SWB','TSA'];
	arrivalList['POB']=['PLH','PSB','PST','PVB','SWB','TSA'];
	arrivalList['POF']=['BEC','KLE','PBB','PPH','PPR','SHW'];
	arrivalList['PPH']=['BEC','KLE','PBB','POF','PPR','SHW'];
	arrivalList['PPR']=['BEC','KLE','PBB','POF','PPH','PSK','SHW'];
	arrivalList['PSB']=['PLH','POB','PST','PVB','SWB','TSA'];
	arrivalList['PSK']=['ALF','PPR'];
	arrivalList['PST']=['PLH','POB','PSB','PVB','SWB','TSA'];
	arrivalList['PVB']=['PLH','POB','PSB','PST','SWB','TSA'];
	arrivalList['PWR']=['CMX','TEX'];
	arrivalList['QDR']=['CAM'];
	arrivalList['SHW']=['BEC','KLE','PBB','POF','PPH','PPR'];
	arrivalList['SLT']=['ERL'];
	arrivalList['SOI']=['ALR','MCN'];
	arrivalList['SWB']=['FUL','PLH','POB','PSB','PST','PVB','TSA'];
	arrivalList['TEX']=['PWR'];
	arrivalList['THT']=['CHM','KPR'];
	arrivalList['TSA']=['DUK','PLH','POB','PSB','PST','PVB','SWB'];
	arrivalList['VES']=['CFT'];
}

/**
 * Returns list of DOM objects (OptGroup) that should be added to a Select object.
 * @param List of terminal objects.
 */
function createSortedOptionList(terminalList){
	var regions = new Array(); 
	terminalList.sort(terminalListComparator);
	
	for(var i=0, len = regionList.length; i<len; i++){
		var group = document.createElement("optgroup");
		group.label = regionList[i];
		regions.push(group);
	}
	for(var i=0, len = terminalList.length; i< len; i++){
		var term = terminalList[i];
		var text = term.location != term.name ? term.location+'-'+term.name : term.name;
		addNewOption(regions[term.region], text, term.id);
	}
	return regions;
}

/**
 * Removes all options and optGroup DOM objects from the given select DOM object.
 */
function clearSelect(selectEl){
	while(selectEl.childNodes.length > 0){
		selectEl.removeChild(selectEl.childNodes[0]);	
	}
}

/**
 * Adds a new DOM 'option' to the given parent element using appendChild().
 */
function addNewOption(parentEl, text, value){
	var opt = document.createElement("option");//setup default.
	parentEl.appendChild(opt);
	opt.value = value;
	opt.text = text;	
}

/**
 * Fetches the arrival combobox, clears its content and then populates it with
 * new values.
 */
function repopulateArrivalCombo(terminalList){
	var el = document.getElementById(arrivalElementId);	
	clearSelect(el);
	addNewOption(el, defaultArrivingLocation, "");
	var regionList = createSortedOptionList(terminalList);
	
	for(var i=0, len = regionList.length; i<len; i++){
		if(regionList[i].childNodes.length > 0){
			el.appendChild(regionList[i]);
		}
	}
}

/**
 * Returns Terminal object based on the code passed in.
 * If a String is passed in a single Terminal is returned.  If an Array is
 * passed in then an Array of Terminals is returned.
 * Assumption: Code passed in exists and is valid!
 */
function getTerminalsFromCode(codeOrList){
	var result = new Array();
	var isSingle = false;
	if(codeOrList[0] != null ){//is an array.
		for(i in codeOrList){
			result.push(terminalMap[codeOrList[i]]);	
		}
	}else {
		result.push(terminalMap[codeOrList]);
		isSingle = true;
	}
	return !isSingle ? result : result[0];
}

/**
 * Compares Terminal objects.  This allows for sorting in Ascending Location name.
 */
function terminalListComparator(a,b){
	var result = 0;
	if(a.location > b.location){
		result = 1;
	}else if(a.location < b.location){
		result = -1;
	}
	return result;
}

/**
 * Function to call once to populate the Departure locations.
 */
function setupDeparture(departureID, arrivalID){
	//alert('Setup departure');
	var el = document.getElementById(departureElementId);
	clearSelect(el);
	addNewOption(el, defaultDepartureText, "");
	
	//Convert the global terminal map into an array.
	var terminalList = new Array();
	for(id in terminalMap){
		terminalList.push(terminalMap[id]);
	}
	
	var regionList = createSortedOptionList(terminalList);
	for(var i=0, len = regionList.length; i<len; i++){
		el.appendChild(regionList[i]);	
	}
	
	if(departureID != ''){
		el.value = departureID;
		if(el.value != departureID){//IE6 fails on this, all other browsers are okay.
			setTimeout(function(){el.value = departureID;}, 1);
		}
		departureChange(departureID, false, true);//do not fire ADF event, but notify FLASH
	}
	if(arrivalID != ''){
		var arr = document.getElementById(arrivalElementId);
		arr.value = arrivalID;
		if(arr.value != arrivalID){//IE6 fails on this, all other browsers are okay.
			setTimeout( function() {arr.value = arrivalID;}, 1);
		}
		arrivalChange(arrivalID, false, true);	
	}
}

/**
 * Programatically sets the terminal ID of the departure drop down. 
 * Note: This method behaves as if user clicked selection but suppresses Flash updates
 * as we assume Flash is calling this method.
 **/
function setDepartureTerminal(terminalID){
	
	var depCombo = document.getElementById(departureElementId);
	if(terminalID != depCombo.value){
		depCombo.value = terminalID;
		departureChange(terminalID, true);
	}
}

/**
 * Programatically sets the terminalID of the arrival drop down.
 * Note: This method behaves as if user clicked selection but suppresses Flash updates
 * as we assume Flash is calling this method.
 */
function setArrivalTerminal(terminalID){
	
	var arrCombo = document.getElementById(arrivalElementId);
	if(terminalID != arrCombo.value){
		arrCombo.value = terminalID;
		arrivalChange(terminalID, true);
	}
}

/**
 * Invoked when Dropdown is changed by the User.  Also invoked by Flash
 */
function departureChange(terminalID, suppressFlashEvent, suppressADFEvent){
	document.getElementById(departHidden).value = terminalID;
	if(terminalID != ''){
		var arrivals = getTerminalsFromCode(arrivalList[terminalID]);
		repopulateArrivalCombo(arrivals);
	}else {
		clearSelect(document.getElementById(arrivalElementId));	
	}
	if(suppressFlashEvent != true){
		BCFflashmapSetStartTerminalCode(terminalID);
	}
	//IF arrival has only one. then populate.
	var arrivEl = document.getElementById(arrivalElementId);
        var arriveValue = arrivEl.value;//IE6 breaks unless we use temp variable.
	if(arrivEl.options.length == 2){//the SELECT text and the one terminal.
		arrivEl.value = arrivEl.options[1].value;
                arriveValue = arrivEl.options[1].value;//For arriveChange event.
		if(arrivEl.value != arrivEl.options[1].value){
			setTimeout( function() {arrivEl.value = arrivEl.options[1].value;}, 1);
		}
	}
	arrivalChange(arriveValue, suppressFlashEvent, suppressADFEvent);//Update the arrival to show '' as departure has changed.
}

function arrivalChange(terminalID, suppressFlashEvent, suppressADFEvent){
	document.getElementById(arriveHidden).value = terminalID;
	if(suppressFlashEvent != true){
		BCFflashmapSetEndTerminalCode(terminalID);
	}
	
	if(suppressADFEvent != true){
		kickADF(arriveHidden, terminalID);
	}
}

//Setup values.
addRegions();
addTerminals();
addArrivals();
