//--------------------------------------------
//        Globals Data Structures
//--------------------------------------------


// Controller Objects for each GUI section
var inputController;
var totalController; // TODO
var flightListController; // TODO

// Templates from HTML
var flightTemplate;
var clearallTemplate;
var flightList;
var noflightTemplate;
var htmlBase = '';

//Number formatting constants
var separatorValue;
var decimalValue;
var localeValue;

function setLanguageLocale(locale) {
	switch(locale) {
		case 'en_gb':
			setLocaleConstants(locale,CARBON_KGS,DISTANCE_MIS,'');
			break;
		case 'en_eu':
			setLocaleConstants(locale,CARBON_KGS,DISTANCE_KMS,COMMA);
			break;
		case 'fr_fr':
			setLocaleConstants(locale,CARBON_KGS,DISTANCE_KMS,PERIOD,COMMA);
			MAPINFO_LABEL_DIST    = 'La Distance totale de Voyage:&nbsp;';
			break;
		case 'de_de':
			setLocaleConstants(locale,CARBON_KGS,DISTANCE_KMS,PERIOD,COMMA);
			MAPINFO_LABEL_DIST    = 'Gesamte Reisenentfernung:&nbsp;';
			MAPINFO_LABEL_CO2     = 'Gesamte CO2:&nbsp;';
			break;
		default:
			setLocaleConstants(locale,CARBON_LBS,DISTANCE_MIS);
			break;
	}
}

function setLocaleConstants(locale, carbon, distance, separator, decimal) {
	this.localeValue = locale;
	setCookie(COOKIE_NAME_LOCALE, this.localeValue, 10);
	setCarbonUnits(carbon);
	setDistanceUnits(distance);
	setGoogleMapTranslation();
	
	if (separator == null)
		separator = this.COMMA;
	if (decimal == null)
		decimal = this.PERIOD;
	
	if (separator == decimal) {
		this.decimalValue = (decimal == this.PERIOD) ? this.COMMA : this.PERIOD;
	} else {
		this.decimalValue = decimal;
	}
	
	this.separatorValue = separator;
}

function setCarbonUnits(type) {
    carbonUnits = type;
}

function setDistanceUnits(type) {
	distanceUnits = type;
}

function setGoogleMapTranslation() {
	var result = localeValue.split('_');
	GOOGLE_API_HL = result[0];
}

function setTrip(rb) {
	var o1 = document.getElementById(rb);
	var v1 = o1.value;
	
	var o2 = document.getElementById('rndtrip');
	o2.setAttribute("value", v1);
}

//-----------------------------------------------
// Main function, called from the HTML onload
//-----------------------------------------------

function getServerFromURL(url) {
    url = ''+url;
    if (url.match(/^[^\/]+:\/\/([^\/]+)\//)) {
        return RegExp.$1;
    }
    return '';
}

function replaceServerInURL(url, server) {
    url = ''+url;
//    alert(url);
    if (url.match(/^([^\/]+:\/\/)([^\/]+)(\/.*)$/)) {
        return RegExp.$1 + server + RegExp.$3;
    }
    return url;
    
}

function baseInit() {
    var myserver = getServerFromURL(window.location.href);

    try {
        var baseString = document.getElementsByTagName('base')[0].
            getAttribute("href");

        var baseserver = getServerFromURL(baseString);
        
        if (baseserver != myserver) {
            if (baseString.match(/^(.*\/)[^\/]*$/)) {
                htmlBase = RegExp.$1;
                htmlBase = replaceServerInURL(htmlBase, myserver);
            }
        }
    } catch(e) {
    }
//    alert('htmlBase: '+htmlBase);
};

function pageInit() {
    mapInit();
    baseInit();

    loadTemplates();

    inputController = new InputController(
        document.getElementById('rndtrip'),
		document.getElementById('from'),
        document.getElementById('to'),
        document.getElementById('numtrips'),
        document.getElementById('addflight'));

    if (!inputController) {
        alert("Could not find input section");
        return;
    }

    totalController = new TotalController(
        document.getElementById('total'),
        document.getElementById('productlink'));
    if (!totalController) {
        alert("Could not find 'total' section");
        return;
    }
    
    flightListController = new FlightListController(document.getElementById('flights'));
    if (!flightListController) {
        alert("Could not find 'total' section");
        return;
    }

    loadSavedData();
}

function loadFlightLeg(n) {
    var srcInfo = new Object;

    if (0) {
    srcInfo.getAttribute = function(name) { return this['A'+name];}
    srcInfo.Adisplay=unescape(getCookie(COOKIE_NAME_F1 + "_" + n));
    srcInfo.Alat=getCookie(COOKIE_NAME_F3 + "_" + n);
    srcInfo.Ahemi=getCookie(COOKIE_NAME_F4 + "_" + n);
    srcInfo.Along=getCookie(COOKIE_NAME_F5 + "_" + n);
    srcInfo.Alhemi=getCookie(COOKIE_NAME_F6 + "_" + n);
    srcInfo.Atype=getCookie(COOKIE_NAME_F7 + "_" + n);
    }
//    srcInfo.Acanon=unescape(getCookie(COOKIE_NAME_F2 + "_" + n));
    srcInfo.savedString = unescape(getCookie(COOKIE_NAME_F1 + "_" + n));
    return srcInfo;
}

function saveFlightLeg(n, srcInfo) {
};

/*
 * Convert airport info string into object
 */
function loadFlightLegInfo(infoString) {
    var infos   = infoString.split('/');
    var srcInfo = new Object;

    srcInfo.getAttribute = function(name) { return this['A'+name];}
    srcInfo.Atype   = infos[0];
    srcInfo.Alhemi  = infos[1];
    srcInfo.Along   = infos[2];
    srcInfo.Ahemi   = infos[3];
    srcInfo.Alat    = infos[4];
    srcInfo.Adisplay= infos[5];
    srcInfo.Acanon  = infos[5];
    
    return srcInfo;
}

/*
 * Convert airport info into a long string
 */
function getFlightLegInfo(srcInfo) {
    if (0) {
    setCookie(COOKIE_NAME_F7 + "_" + n,srcInfo.getAttribute('type'));
    setCookie(COOKIE_NAME_F6 + "_" + n,srcInfo.getAttribute('lhemi'));
    setCookie(COOKIE_NAME_F5 + "_" + n,srcInfo.getAttribute('long'));
    setCookie(COOKIE_NAME_F4 + "_" + n,srcInfo.getAttribute('hemi'));
    setCookie(COOKIE_NAME_F3 + "_" + n,srcInfo.getAttribute('lat'));
    setCookie(COOKIE_NAME_F1 + "_" + n,srcInfo.getAttribute('display'));
    }
    var savedString = srcInfo.getAttribute('type') + '/' +
        srcInfo.getAttribute('lhemi') + '/' +
        srcInfo.getAttribute('long') + '/' +
        srcInfo.getAttribute('hemi') + '/' +
        srcInfo.getAttribute('lat') + '/' +
        srcInfo.getAttribute('canon');
        
//    setCookie(COOKIE_NAME_F2 + "_" + n,srcInfo.getAttribute('canon'));
//    setCookie(COOKIE_NAME_F1 + "_" + n,savedString);
    return savedString;
}


function loadSavedData() {
    var nlegs = parseInt(getCookie(COOKIE_NAME_N));
    var srcInfo, dstInfo;
    var newflight, fc;
    var n = 0;
    if (isNaN(nlegs))
        nlegs = 0;
        
    for (n=nlegs-1; n>=0; n--) {
        try {

            var info = unescape(getCookie(COOKIE_NAME_NTRIPS + '_' + n));
            var infos = info.split('@');

            if (0) {
            alert(infos[0] + '\n' + 
                  infos[1] + '\n' + 
                  infos[2] + '\n' + 
				  infos[3]);
            }

            var rtrip = parseInt(infos[3]);
			var ntrips = parseInt(infos[2]);
            var srcInfo = loadFlightLegInfo(infos[1]);
            var dstInfo = loadFlightLegInfo(infos[0]);

            newflight = flightTemplate.cloneNode(true);
            fc = new FlightController(rtrip,
									  srcInfo,
                                      dstInfo,
                                      newflight,
                                      ntrips);
            
            fc.refresh();

            if (0) {
				var rtrip  = parseInt(getCookie(COOKIE_NAME_RTRIP  + '_' + n));
				var ntrips = parseInt(getCookie(COOKIE_NAME_NTRIPS + '_' + n));
				if (isNaN(ntrips))
					ntrips = 1;
	
				srcInfo = loadFlightLeg('src'+n);
				dstInfo = loadFlightLeg('dst'+n);
	
				alert(srcInfo.savedString + "\n" + dstInfo.savedString);
            }
        } catch(e) {
        }
    }
}

function loadTemplates() {
    flightTemplate = document.getElementById('flightTemplate');
    if (!flightTemplate) {
        alert("Could not find flight template");
        return;
    }

    noflightTemplate = document.getElementById('noflightTemplate');
    if (!noflightTemplate) {
        alert("Could not find noflight template");
        return;
    }

    if (0) {
    clearallTemplate = document.getElementById('clearallTemplate');
    if (!clearallTemplate) {
        alert("Could not find flight control template");
        return;
    }
    }

    flightList = document.getElementById('flights');
    if (!flightList) {
        alert("Could not find flight list element");
        return;
    }

}

// Return the URL to fetch airports based on the keyword
function GetAirportListUrl(ac, keyword) {
    return url = AIRPORT_LIST_URL + keyword;
}

//-----------------------------------------------
//              Distance Functions
//-----------------------------------------------

function calculateDistance(lat1, long1, lat2, long2) {
    var er = 6366.707;

    //ave. radius = 6371.315 (someone said more accurate is 6366.707)
    //equatorial radius = 6378.388
    //nautical mile = 1.15078
    var radlat1 = Math.PI * (lat1)/180;
    var radlat2 = Math.PI * (lat2)/180;
    
    //now long.
    var radlong1 = Math.PI * (long1)/180;
    var radlong2 = Math.PI * (long2)/180;
    //spherical coordinates x=r*cos(ag)sin(at), y=r*sin(ag)*sin(at), z=r*cos(at)
    //zero ag is up so reverse lat

    radlat1 += Math.PI/2;
    radlat2 += Math.PI/2;

    if (radlong1<0)
        radlong1 += Math.PI*2;

    if (radlong2<0)
        radlong2 += Math.PI*2;

    var x1 = er * Math.cos(radlong1)*Math.sin(radlat1);
    var y1 = er * Math.sin(radlong1)*Math.sin(radlat1);
    var z1 = er * Math.cos(radlat1);
    
    var x2 = er * Math.cos(radlong2)*Math.sin(radlat2);
    var y2 = er * Math.sin(radlong2)*Math.sin(radlat2);
    var z2 = er * Math.cos(radlat2);
    
    var d = Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
    
    //side, side, side, law of cosines and arccos
    var theta = Math.acos((er*er+er*er-d*d)/(2*er*er));
    var distance = theta*er;

    return distance/1.609344; // in miles
}

//-----------------------------------------------
//               Filters
//-----------------------------------------------

InputController.prototype.filterNumTrips = function(input, e) {
    var selectionLength;

    if (typeof(input.selectionStart) != 'undefined') {
        selectionLength = input.selectionEnd - input.selectionStart;
    } else {
        try {
            selectionLength = document.selection.createRange().text.length;

        } catch(e) {
        }
    }

    if (!input.prevValue)
        input.prevValue = 1;

    if (e) {
        var code =  e.keyCode? e.keyCode : e.charCode;

        switch (code) {
        case KEY_ENTER:
            this.eventAddFlight();
            return false;
            break;

        case KEY_ESC:
            input.value = 1;
            return false;

        case KEY_LEFT:
        case KEY_RIGHT:
        case KEY_UP:
        case KEY_DOWN:
        case KEY_DELETE:
        case KEY_BACKSPACE:
        case KEY_TAB:
            return true;

        default:
            if (input.value.length - selectionLength >=2 || (code < 48 || code > 57)) {
                return false;
            }
        }
    } else {
        if (input.value == 0 || input.value == '')
            input.value = 1;

        if (input.value.match(/^0+(.*)/)) {
            input.value = RegExp.$1;
        }
    }

    input.prevValue = input.value;
    return true;
};

//-----------------------------------------------
//               Controllers
//
// Each controller object represents an UI section.
//
//-----------------------------------------------

//--------------------------------------------
//   InputController Object: Controller object 
//   for the input fields.
//
//	 Modified: 2007/03/19 by Phillip Jordan
//	rtrip:	   input element for roundtrip or one-way
//
//  source:    input element for departure
//  dest:      input element for arrival
//  ntrips:    input element for numtrips
//  addFlight: button element for adding the flight
//--------------------------------------------
function InputController(rtripInput, sourceInput, destInput, ntripsInput, addFlightButton) {
    var view = new Object;

    if (!rtripInput || 
		!sourceInput || 
        !destInput ||
        !ntripsInput ||
        !addFlightButton) {
        alert('Input elements missing');
        return null;
    }

    /* data */
    this.fromAirport = new AutoComplete(sourceInput,
                                        GetAirportListUrl,
                                        this.setFocus.bind2(this,1),
                                        0);
    
    this.toAirport   = new AutoComplete(destInput,
                                        GetAirportListUrl,
                                        this.setFocus.bind2(this,2),
                                        0);

    /* error check */
    if (!this.fromAirport ||
        !this.toAirport) {
        alert("ERROR");
        return null;
    }
    

    /* view */
    this.view      = view;
	view.rtrip	   = rtripInput;
    view.src       = sourceInput;
    view.dst       = destInput;
    view.ntrips    = ntripsInput;
    view.addFlight = addFlightButton;

    AttachEvent(view.addFlight, 'onclick', this, 'eventAddFlight');
    SetInputFilter(ntripsInput, this.filterNumTrips.bind(this));

    rtripInput.disabled = false;
	sourceInput.disabled = false;
    destInput.disabled = false;
    ntripsInput.disabled = false;
    addFlightButton.disabled = false;
    this.setFocus(0);
}

//--------------------------------------------
// Focus on a particular input element:
//
// 0 - Departure airport
// 1 - Arrival airport
// 2 - Numtrips
// 3 - Add flight button
//--------------------------------------------
InputController.prototype.setFocus = function(i) {
    try {
        switch (i) {
            case 0:
            this.fromAirport.setFocus();
            break;
            
            case 1:
            this.toAirport.setFocus();
            break;
            
            case 2:
            this.view.ntrips.focus();
            this.view.ntrips.select();
            break;
            
            case 3:
            this.view.addFlight.focus();
            break;
            
            default:
            this.fromAirport.setFocus();
        }
    } catch(e) {
        alert('InputController.setFocus - Error: '+e.message);
    }
    return false;
};

//----------------------------------------------------
// Called when the user clicks the add flight button
//
// Checks errors and if everything valid, creates
// a new flight entry and updates the downstream UI.
//-----------------------------------------------------
InputController.prototype.eventAddFlight = function() {
    try {
    var view = this.view;
    var newflight;
    var fc;

    var fromInfo = this.fromAirport.selection();
    var toInfo   = this.toAirport.selection();

    if (!fromInfo) {
        if (this.fromAirport.input.value) 
            alert("We were unable to find your departure city. Try entering an airport code, or just type the first few letters of the city name.");
        else
            alert("Please enter a departure city.");
        this.setFocus(0);
        return false;
    }

    if (!toInfo) {
        if (this.toAirport.input.value) 
            alert("We were unable to find your arrival city. Try entering an airport code, or just type the first few letters of the city name.");
        else
            alert("Please enter an arrival city.");
        this.setFocus(1);
        return false;
    }

    if (fromInfo.getAttribute('display') ==
        toInfo.getAttribute('display')) {
        alert('Arrival and departure airports are the same.  Please enter different start and end points.');
        this.setFocus(0);
        return false;
    }

    newflight = flightTemplate.cloneNode(true);
    fc = new FlightController(this.view.rtrip.value,
							  fromInfo,
                              toInfo,
                              newflight,
                              this.view.ntrips.value);

    fc.refresh();
    
	document.getElementById("r1").checked=true;
	view.rtrip.value = '2';
	
    this.fromAirport.clear();
    this.toAirport.clear(); 

    view.ntrips.value = '1';
    this.setFocus(0);
    } catch(e) {
    }

	__utmSetVar('calc/flight'); 
	__utmSetVar('calc/any'); 

	return false;
};

//--------------------------------------------
//   TotalController Object: Controller object 
//   for 'total' widget
//
//  totalDiv: HTML element for the 'total' widget.
//  productDiv: HTML element for the 'total' widget.
//--------------------------------------------
function TotalController(totalDiv, productDiv) {
    var view = new Object;

    /* data */
    this.miles = 0;
    this.carbon = 0;

    /* View */
    this.view    = view;
    view.total   = totalDiv;
    view.product = productDiv;

    view.totalMiles   = GetElementById(totalDiv, 'totalmiles');
    view.totalCarbon  = GetElementById(totalDiv, 'totalcarbon');
    view.totalCarbonLBS  = GetElementById(totalDiv, 'totalcarbonLBS');

    view.productMiles     = GetElementById(productDiv, 'totalmiles');
    view.productCarbon    = GetElementById(productDiv, 'totalcarbon');
    view.purchaseLink     = GetElementById(productDiv, 'purchase_link');
	view.productCarbonLbs = GetElementById(productDiv, 'totalcarbonlbs');
		
    this.refresh();
}

//----------------------------------------------
// called when any flight info changes, to 
// recalculate the totals
//----------------------------------------------
TotalController.prototype.update = function() {
    this.miles = flightListController.miles;
    this.carbon = flightListController.carbon;

    // Update the cookies
    setCookie(COOKIE_NAME_MILES, Math.round(this.miles), 10);
    setCookie(COOKIE_NAME_CARBON, Math.round(this.carbon), 10);

    this.refresh();
};

//----------------------------------------------
// refresh display
//----------------------------------------------
TotalController.prototype.refresh = function() {
    var view = this.view;
	var tons = Math.round(this.carbon / 2000);
	var mts  = convertToMTS(this.carbon);
	var kgs  = convertToKGS(this.carbon);
	
	var kms  = convertToKMS(this.miles);

    if (!this.miles) {
        hide_element(view.total);
        hide_element(view.product);
    } else {
        show_element(view.total);
        show_element(view.product);
		
		if (distanceUnits == DISTANCE_KMS) {
			if (view.productMiles) 	   { view.productMiles.innerHTML  = formatNumber(kms) + " km"; }
			view.totalMiles.innerHTML  = formatNumber(kms) + " km";
		} else {
			if (view.productMiles) { view.productMiles.innerHTML  = formatNumber(this.miles) + " miles"; }
			view.totalMiles.innerHTML  = formatNumber(this.miles) + " miles";
		}

        if (carbonUnits == CARBON_MTS) {
			//productCarbonLbs
            view.totalCarbon.innerHTML = formatNumber(mts, true) + ((mts < 2) ? " mT" : " mTs");
            if (view.productCarbon)    { view.productCarbon.innerHTML = formatNumber(mts, true) + ((mts < 2) ? " mT" : " mTs"); }
            //if (view.purchaseLink)     { view.purchaseLink.href=MTS_PUSRCHASE_LINK + Math.round(mts); }
			//if (view.productCarbonLbs) { view.productCarbonLbs.innerHTML = formatNumber(this.carbon, true); }
		} else if (carbonUnits == CARBON_KGS) {
			view.totalCarbon.innerHTML = formatNumber(kgs) + " kg";
			if (view.productCarbon)    { view.productCarbon.innerHTML = formatNumber(kgs) + " kg"; }
		} else {
            view.totalCarbon.innerHTML = formatNumber(this.carbon) + " lbs";
            if (view.productCarbon) { view.productCarbon.innerHTML = formatNumber(tons) + ((tons == 1) ? " ton" : " tons"); }
			//if (view.productCarbonLbs) { view.productCarbonLbs.innerHTML = formatNumber(this.carbon); }
		}

        if (view.totalCarbonLBS) {
            view.totalCarbonLBS.innerHTML = formatNumber(this.carbon) + " lbs";
        }

    }
};

//--------------------------------------------
//   FlightListController Object: Controller object 
//   each flight in the flight list.
//---------------------------------------------
function FlightListController(div) {
    var view = new Object;
    this.view = view;

    /* Data */
    this.miles  = 0;
    this.carbon = 0;

    this.flightControllers = new Array();

    /* view */
    view.div = div;
    view.clearallControls  =  document.getElementById('clearallControls');
    view.clear_all = document.getElementById('clear_all');
    view.clear_all_icon = document.getElementById('clear_all_icon');

    AttachEvent(view.clear_all, 'onclick', this, 'removeAll');
//    AttachEvent(view.clear_all, 'onclick', this, 'testCookies');

    AttachEvent(view.clear_all_icon, 'onclick', this, 'removeAll');

    div.controller = this;

    
}

FlightListController.prototype.testCookies = function() {
    var miles = getCookie(COOKIE_NAME_MILES);
    var carbon = getCookie(COOKIE_NAME_CARBON);

    alert('Saved miles:'+miles+' carbon:'+carbon);
    return false;
};


FlightListController.prototype.update = function() {
    var i = 0;

    this.miles = 0;
    this.carbon = 0;

    for (i=0; i<this.flightControllers.length; i++) {
        var controller = this.flightControllers[i];

        this.miles  += controller.distance();
        this.carbon += controller.get_carbon();

        //XXX
        var dstinfo = getFlightLegInfo(controller.dst);
        var srcinfo = getFlightLegInfo(controller.src);
        
        //XXX
        
        setCookie(COOKIE_NAME_NTRIPS + '_'+i, 
                  dstinfo + '@' +srcinfo + '@' + controller.numtrips + '@' + controller.rndtrip);
		setCookie(COOKIE_NAME_RTRIP + '_'+i,
				  controller.rndtrip);
    }

    setCookie(COOKIE_NAME_N, this.flightControllers.length);

    this.refresh();
    totalController.update();
};

FlightListController.prototype.refresh = function() {
    var i=0;
    var div = this.view.div;

    while(div.childNodes.length) {
        div.removeChild(div.childNodes[0]);
    }

//    div.appendChild(flightTemplate.cloneNode(true));
//    return;

    for (i=0; i<this.flightControllers.length; i++) {
        var flightDiv = this.flightControllers[i].getDiv();

        show_element(flightDiv);
        flightDiv.style.opacity = 0.98;
        div.appendChild(flightDiv);
    }

    if (i <= 0) {
        var noflight = noflightTemplate.cloneNode(true);
        show_element(noflight);
        hide_element(this.view.clearallControls);
        div.appendChild(noflight);
        mapDefaultView();
    } else {
        show_element(this.view.clearallControls);
        if (this.activeController) {
            this.activeController.center();
        }
    }

};

FlightListController.prototype.setActive = function(flightController) {
    this.activeController = flightController;
};

FlightListController.prototype.add = function(flightController) {
    this.flightControllers.unshift(flightController);
    this.setActive(flightController);

    this.update();
    flightController.fade();
    return false;
};

FlightListController.prototype.remove = function(flightController) {
    list_remove(this.flightControllers, flightController);
    if (this.activeController == flightController) {
        if (this.flightControllers.length > 0)
            this.activeController = this.flightControllers[0];
        else
            this.activeController = null;
    }

    this.update();
    return false;
};

FlightListController.prototype.removeAll = function(flightController) {
    try {
    var templist = new Array();
    var i=0;
    while (i<this.flightControllers.length) {
        templist.push(this.flightControllers[i]);
        i++;
    }
    
    i =0;
    while (i<templist.length) {
        templist[i].fadeOut(true);
        i++;
    }
    } catch(e) {
    }

    try {
    this.update();
    } catch(e) {
    }
    return false;
};


//--------------------------------------------
//   FlightController Object: Controller object 
//   each flight in the flight list.
//
//  src: Autocompletion Info for departure flight
//  dst: Autocompletion Info for arrival flight
//  div: HTML element to display the flight info.
//       Should be a clone of flightTemplate.
//--------------------------------------------
function FlightController(rtrip, src, dst, div, ntrips) {
    var view  = new Object;
    this.view = view;

    /* Data */
    this.removing = false;
	this.rndtrip = rtrip;
    this.src = src;
    this.dst = dst;
    this.miles = 0;
    this.carbon = 0;
    this.displayed = false;
    this.mapController = null;

    this.numtrips = ntrips;
    if (isNaN(this.numtrips))
        this.numtrips = 1;

    div.controller  =  this;

    /* View */
    view.div        =  div;
	view.rtrip		=  GetElementById(div, 'rtrip');
    view.route      =  GetElementById(div, 'route');
    view.flightinfo =  GetElementById(div, 'flightinfo');
    view.inc        =  GetElementById(div, 'increase');
    view.dec        =  GetElementById(div, 'decrease');
    view.trash      =  GetElementById(div, 'trash');
    view.ntrips     =  GetElementById(div, 'ntrips');

    view.inc.onclick   = this.increase.bind(this);
    view.dec.onclick   = this.decrease.bind(this);
    view.trash.onclick = this.fadeOut.bind(this);

    this.update();
}

//----------------------------------------------
// Remove flight from the flight list
//----------------------------------------------
FlightController.prototype.remove = function() {
    flightListController.remove(this);
    if (this.mapController) {
        try {
        this.mapController.remove();
        } catch(e) {
        }
    }

    return false;
};

FlightController.prototype.getDiv = function() {
    return this.view.div;
};

//----------------------------------------------
// Called when numtrips changes, to
// recalculate the carbon.
//----------------------------------------------
FlightController.prototype.update = function() {
    var lat1, lat2, long1, long2;
    var miles;

    // Calculate Distance
    lat1  = this.src.getAttribute('lat');
    lat2  = this.dst.getAttribute('lat');
    
    long1 = this.src.getAttribute('long');
    long2 = this.dst.getAttribute('long');

    this.miles = this.numtrips * this.rndtrip * calculateDistance(lat1, long1, 
                                                       lat2, long2);

    // Calculate Carbon
    this.carbon = calculateCarbon(this.miles, 1);

    if (!this.mapController && 1 /* XXX */) {
        this.mapController = new FlightMapController(this,
                                                     lat1, long1,
                                                     lat2, long2);
    }

    // Re display the info
    this.refresh();

    if (flightListController)
        flightListController.update();    
};

//----------------------------------------------
// Refresh the display of the flight info
//----------------------------------------------
FlightController.prototype.refresh = function() {
    var view  = this.view;

    var miles = formatNumber(this.miles);
	var kms = convertToKMS(this.miles);
	
    var carbon 	= formatNumber(this.carbon);
    var mts		= convertToMTS(this.carbon);
	var kgs		= convertToKGS(this.carbon);

    var name1 = formatName(this.src.getAttribute('canon'));
    var name2 = formatName(this.dst.getAttribute('canon'));
    
    this.departureCityName = name1;
    this.arrivalCityName   = name2;

	if (this.rndtrip == 1) {
		view.route.innerHTML = name1 + ' <span class="arrow"><img src="/ect/shared/img/calculator/rarr.gif" border="0"></span> ' + name2;
	} else {
		view.route.innerHTML = name1 + ' <span class="arrow"><img src="/ect/shared/img/calculator/harr.gif" border="0"></span> ' + name2;
	}
    
    if (carbonUnits == CARBON_MTS) {
        view.flightinfo.innerHTML = miles + ' miles : ' + formatNumber(mts, true) + ((mts < 2) ? " mT" : " mTs") + ' CO' +
        '<span class="sub">2</span>'; 
    } else if (carbonUnits == CARBON_KGS) {
		view.flightinfo.innerHTML = ((distanceUnits == DISTANCE_KMS) ? formatNumber(kms) + " km" : miles + " miles") + ' : ' + formatNumber(kgs) + " kg" + ' CO' +
        '<span class="sub">2</span>'; 
		
	} else {
        view.flightinfo.innerHTML = miles + ' miles : ' + carbon + ' lbs CO' +
        '<span class="sub">2</span>'; 
    }
	
	try {
		switch(localeValue) {
			case 'de_de':
				tripLabel = " flug";
				ntripLabel= " fl&#252;ge";
				break;
			case 'fr_fr':
				tripLabel = " voyage";
				ntripLabel= " voyages";
				break;
			default:
				tripLabel = " trip";
				ntripLabel= " trips";
				break;
		}
	} catch(e) {
    
	}
	
    if (this.numtrips == 1)
        view.ntrips.innerHTML = this.numtrips + tripLabel;
    else
        view.ntrips.innerHTML = this.numtrips + ntripLabel;

    if (!this.displayed) {
        flightListController.add(this);

        this.displayed = true;
    }

    //???
    if (this.mapController)
        this.mapController.refresh();
};

FlightController.prototype.center = function() {
    if (this.mapController)
        this.mapController.center();
};

//----------------------------------------------
// Distance for this flight
//----------------------------------------------
FlightController.prototype.distance = function() {
    if (!this.removing)
        return this.miles;
    return 0;
};

//----------------------------------------------
// Total carbon for this flight
//----------------------------------------------
FlightController.prototype.get_carbon = function() {
    var miles = this.distance();
    return calculateCarbon(miles, 1);
};

//----------------------------------------------
// Increase the number of trips
//----------------------------------------------
FlightController.prototype.increase = function() {
    try {
    flightListController.setActive(this);
    if (this.numtrips < 99) {
        this.numtrips++;
    }
    this.update();

    inputController.setFocus(0);
    } catch(e) {
    }
    return false;
};

//----------------------------------------------
// Decrease the number of trips
//----------------------------------------------
FlightController.prototype.decrease = function() {
    try {
    flightListController.setActive(this);
    if (this.numtrips > 1) {
        this.numtrips--;
    }
    this.update();

    inputController.setFocus(0);
    } catch(e) {
    }
    return false;
};

//----------------------------------------------
// Do the fade effect - fade from yellow to white
//----------------------------------------------
FlightController.prototype.fade = function() {
    this.fadestep = FADE_NSTEPS;
    setTimeout(this.fadeUpdate.bind(this), FADE_INTERVAL);

    return false;
};

//----------------------------------------------
// Do the fade out effect - fade from yellow to white
//----------------------------------------------
FlightController.prototype.fadeOut = function(removingAll) {
    try {
    if (this.mapController) {
        setTimeout(this.mapController.remove.bind(this.mapController),
                   100);
    }

    this.removing = true;
    if (removingAll != true)
        this.update();

    this.fadestep = FADE_NSTEPS;

    this.fadeAlpha   = 100;
    this.deltaAlpha  = 100 / FADE_NSTEPS;

    this.totalHeight  = findHeight(this.view.div);
    // IE Hack
    setHeight(this.view.div, this.totalHeight);
    this.deltaHeight  = this.totalHeight / FADE_NSTEPS;

    if (removingAll == true) {
        this.totalHeight = 0;
    }

    setTimeout(this.fadeOutUpdate.bind(this), FADE_OUT_INTERVAL);
    } catch(e) {
    }

    return false;
};


// Private method
FlightController.prototype.fadeUpdate = function() {
    var bgcolor = '#';
    var i=0;
    var color;

    for (i=0; i<3; i++) {
        color = Math.round(255 - (255 - FADE_COLOR[i]) * this.fadestep / FADE_NSTEPS);
        bgcolor = bgcolor + dec2hex(color);
    }

    this.view.div.style.backgroundColor = bgcolor;

    if (this.fadestep > 0) {
        this.fadestep--;
        setTimeout(this.fadeUpdate.bind(this), FADE_INTERVAL);
    }

    return false;
};

FlightController.prototype.fadeOutUpdate = function() {
    if (this.fadeAlpha >= 0) {
        this.fadeAlpha -= this.deltaAlpha;
        setOpacity(this.view.div, this.fadeAlpha);

        setTimeout(this.fadeOutUpdate.bind(this), FADE_OUT_INTERVAL);
    } else if (this.totalHeight > 0) {
        setOpacity(this.view.div, 0);
        
        this.totalHeight -= this.deltaHeight;
        setHeight(this.view.div, this.totalHeight);

        setTimeout(this.fadeOutUpdate.bind(this), ROLL_IN_INTERVAL);
    } else {
        // finish
        this.remove();
        return false;
    }


    return false;
}

function calculateCarbon(miles, ntrips) {
    var i;
    var co=0;

    for (i=0; i < CC_FACTORS.length; i++) {
        co = CC_FACTORS[i].co;
        if ((miles / 2) < CC_FACTORS[i].miles) {
            break;
        }
    }

    return (miles*co*ntrips);
}

//--------------------------------------------
// Convert 12345678 -> 12,345,678
//--------------------------------------------

function formatCommas(number) {
    var str = ''+number;
    var ans = '';

    while (str.length > 3) {
        var l = str.length;

        if (ans)
            ans = this.separatorValue + ans;
        ans = str.substring(l-3, l) + ans;
        str = str.substring(0, l-3);
    }

    if (ans)
        ans = this.separatorValue + ans;
    ans = str + ans;

    return ans;
}

function formatNumber(miles, decimals) {
    if  (!decimals)
        decimals=0;

    miles = '' + miles;

    // We are interested in only single decimal point
    if (miles.match(/^(.*)(\..)/)) {
        if (decimals){
            return formatCommas(parseInt(RegExp.$1)) + this.decimalValue + (RegExp.$2 * 10);
		}
        else{
            return formatCommas(parseInt(RegExp.$1));}
            
//        return miles;
    } else {
        if (decimals)
            return formatCommas(parseInt(miles)) + this.decimalValue + "0";
        else
            return formatCommas(parseInt(miles));
    }
}

//--------------------------------------------
// Replace space with &nbsp; in airport names.
//--------------------------------------------

function formatName(name) {
    return name.replace(/ /g, "&nbsp;");
}

// Airport selected via autocomplete.
function eventAirportSelected(ac) {
}


//--------------------------------------------
// Weight & Distance Measurements conversions.
//
// Modified: 2007/03/27 by Phillip Jordan
// 
//--------------------------------------------

function convertToKMS(miles) {
	var kms  = miles * KMS_MIS;
	return kms;
}

function convertToKGS(pounds) {
	var kgs  = Math.round(pounds * 10000000 / KGS_LBS)/10000000;
	return kgs;
		
}

function convertToMTS(pounds) {
	var mTs  = Math.round(pounds * 10000 / MTS_LBS)/10000;
	return mTs;
		
}




