/* $Id: enf.js,v 1.9 2005/06/16 00:00:08 geoff Exp $ */
/* Copyright (c) 2000-2004 Peck Labs, Inc. All rights reserved. */

function PopFAA(url) {
    FAApopup = window.open('', 'FAApopup', 'scrollbars=1');
    FAApopup.location.href = url;
    if (FAApopup.opener === null) FAApopup.opener = window;
    FAApopup.focus();
}

function Pop(url) {
    popup = window.open('', 'popup', 'height=320,width=450,scrollbars=1');
    popup.location.href = url;
    if (popup.opener === null) popup.opener = window;
    popup.focus();
}

function PopTR() {
    popup = window.open('', 'TravelPopup', 'scrollbars=1');
    popup.location.href = 'http://www.travelstoremaker.com/cgit/porch?agentid=enflight';
    if (popup.opener === null) popup.opener = window;
    popup.focus();
}

function PopP(url) {
    popup = window.open('', 'Procedure', 'width=620,scrollbars=1');
    popup.location.href = url;
    if (popup.opener === null) popup.opener = window;
    popup.focus();
}

function PopH(url) {
    popup = window.open('', 'Help', 'width=500,height=500,scrollbars=1');
    popup.location.href = url;
    if (popup.opener === null) popup.opener = window;
    popup.focus();
}

function PopAPD(url) {
    popup = window.open('', 'AirportDiagram', 'width=620,scrollbars=1');
    popup.location.href = url;
    if (popup.opener === null) popup.opener = window;
    popup.focus();
}

function PopBig(url) {
    popup = window.open('', 'pop', 'height=520,width=720,scrollbars=1');
    popup.location.href = url;
    if (popup.opener === null) popup.opener = window;
    popup.focus();
}

function aopaDir (a) {
    var f;
    f = a.charAt(0).toUpperCase();
    if ( a.length == 4 && isalpha(a) && (f == 'K' || f == 'P' || f == 'C' || f == 'M')) {
	a = a.substring(1,4);
    }
    aopadir = window.open('', 'aopadir', 'toolbar=1,scrollbars=1,location=0,statusbar=0,menubar=1,resizable=1,width=640,height=480');
    aopadir.location.href = 'http://www.aopa.org/members/airports/detail.cfm?identifier=' + a;
    if (aopadir.opener === null) aopadir.opener = window;
    aopadir.focus();
}

function aptDir (a) {
    var f;
    f = a.charAt(0).toUpperCase();
//    if ( a.length == 4 && isalpha(a) && (f == 'K' || f == 'P' || f == 'C' || f == 'M')) {
//	a = a.substring(1,4);
//    }
//    win = window; // or enfMapObj ? or     olMapDiv=document.getElementById('enfMapDiv');
    dw = window.open('', 'aptdir', 'toolbar=1,scrollbars=1,location=0,statusbar=0,menubar=1,resizable=1,width=660,height=480');
    dw.location.href = 'apt.php?p=1&id=' + a;
    if (dw.opener === null) dw.opener = window;
    dw.focus();
}

function hideItem(id) {
    document.getElementById(id).style.display='none';
}

function showItem(id) {
    document.getElementById(id).style.display='inline';
}

function isalpha(s) {
    var i;
    for ( i = 0 ; i < s.length ; i++ )
	if ( !((s.charAt(i) >= 'A' && s.charAt(i) <= 'Z') || (s.charAt(i) >= 'a' && s.charAt(i) <= 'z')) )
	    return false;
    return true;
}

function calcTimeOffset()
{
    var current = new Date();

    var offset = current.getTime() - " . time() * 1000 . "; 
    return offset;
}
var offset = calcTimeOffset();

function currentTime()
{
    var current = new Date();
    current = new Date(current.getTime() - offset);
    var utctime = current.toGMTString();
    utctime = '&nbsp;&nbsp;' + utctime.substring(0, utctime.length - 7) + ' UTC&nbsp;&nbsp;';
    if (document.all) {
	document.all.clockDiv.innerHTML = utctime;
	setTimeout('currentTime()', 1000);
    // } else if (document.layers) { 
	// This doesn't work in Netscape 4.x unless clockDiv is
	// positioned absolutely.
	//document.clockDiv.document.open()
	//document.clockDiv.document.write(utctime);
	//document.clockDiv.document.close()
	//setTimeout('currentTime()', 1000);
    // } else if (document.getElementById) {
	// Netscape 6
	// document.getElementById('clockDiv').innerHTML = utctime;
	// setTimeout('currentTime()', 1000);
    }
}


// Extends the Array type to have a 'last' function which returns its last element
// This is like pop(), except that it doesn't remove the element, it just returns it.
// Yes, I know modifying low-level objects like this is a bad idea.

Array.prototype.last = function() {
    return this[this.length - 1];
};

// This is *not* used
// To cover IE 5 Mac lack of the push method
// Array.prototype.push = function(value) {
//     this[this.length] = value; 
// };

// This really should extend the Array.protoype as well.  Aparently decrementing is provably faster.
// I also love the little while construct ... -- nick

function contains(a, obj) {
    var i = a.length;
    while (i--) {
	if (a[i] === obj) {
	    return true;
	}
    }
    return false;
}


// // IE prior to version 9 does not support the Array.map function.
// // So we roll our own.  THIS DID NOT WORK
// if (Array.prototype.map == undefined) {

//     Array.prototype.map = function (functionToBeMapped){
// 	alert(this.length);
// 	for (index=0; index < this.length; index++) {
// 	    // Fortunately JS silently deals with functionsToBeMapped that take less than three args.
// 	    // Only the first arg is required
// 	    alert( index);
// 	    functionToBeMapped(this[index], index, this);
// 	}
//     };
// }

// THIS WORKED
// from http://www.xinotes.org/notes/note/884/
if(typeof Array.prototype.map !== 'function') {
    Array.prototype.map = function(fn) {
	for (i=0, r=[], l = this.length; i < l; r.push(fn(this[i++])));
	return r;
    };
}


// Only works for two arrays
function intersection (a1, a2) {
    resultArray = new Array();
    a1.map(function (elt, idx) {
	    if ( contains(a2, elt)) {resultArray.push(elt)};
	});
    return resultArray;
}


// // The following 3 functions from 
// // http://www.developertutorials.com/tutorials/javascript/enumerating-javascript-objects-060822-999/
// // array-like enumeration  // mozilla already supports this
// // if (Array.forEach == undefined) {

// Array.forEach = function(object, block, context) {
//     for (var i = 0; i < object.length; i++) {
//         block.call(context, object[i], i, object);
//     }
// };


// // The following 2 functions from 
// // http://www.developertutorials.com/tutorials/javascript/enumerating-javascript-objects-060822-999/
// // generic enumeration
// Function.prototype.forEach = function(object, block, context) {    
//     for (var key in object) {        
// 	if (typeof this.prototype[key] === 'undefined') {            
// 	    block.call(context, object[key], key, object);        
// 	}    
//     }};


// // from http://www.developertutorials.com/tutorials/javascript/enumerating-javascript-objects-060822-999/
// // globally resolve forEach enumeration
// var forEach = function(object, block, context) {    
//     if (object) {        
// 	var resolve = Object; // default        
// 	if (object instanceof Function) {                 // functions have a "length" property            
// 	    resolve = Function;        
// 	} else if (object.forEach instanceof Function) {  // the object implements a custom forEach method so use that            
// 	    object.forEach(block, context);            
// 	    return;        
// 	} else if (typeof object.length == "number") {    // the object is array-like            
// 	    resolve = Array;        
// 	}        
// 	resolve.forEach(object, block, context);    
//     }};



// Get and set cookies.  This is internal now, new code should use getEnfUI/setEnfUI

// The browser thinks cookies are strings.  So we've wrapped them in JSON
// serialize and de-serialize so we can pretend they are *actually* JS
// objects.

// Cookie management code via blazonry.com/javascript/cookies.php with flavor
// Expires behaves badly if your browser is set to flush all cookies at the
// end of the session It never records the expire date at all, just sets
// everything to "end of session" (AFAICT) Must wonder what this does to
// cookies that are set for, say, 3 seconds in the future?

// All date code in here now.  I don't want to think about the details.
// Everytime we write a cookie it will get a new expiredate

// http://stackoverflow.com/questions/1062963/how-do-browser-cookie-domains-work
// http://www.webreference.com/js/column8/functions.html

// This grabs the last two pieces of the hostname e.g. "rho.net' or "enflight.com" for use by the cookie code
var enfHostname = document.location.hostname.split(".");
var enfDomain = enfHostname[enfHostname.length - 2] + "." + enfHostname[enfHostname.length - 1];

function setCookie(name, value) {
    // Setup a cookie expire date
    var exp = new Date();
    exp.setTime(exp.getTime() + (1000 * 60 * 60 * 24 * 40));     // 40 days ahead
    var expc = (exp == null) ? "" : "; expires=" + exp.toGMTString();

    document.cookie = name + "=" + JSON.stringify(value) + 
        "; path=/" + expc +  "; domain=." + enfDomain + ";";
}


// You must search for cookies by name, as someone was too lazy to provide
// this function pre-defined
// We pretend what is stored in cookies is Javascript Objects

function getCookie (name) {
    var dc = document.cookie;
    var cname = name + "=";

    if (dc.length > 0) {
        begin = dc.indexOf(cname);
        if (begin != -1) {
            begin += cname.length;
            end = dc.indexOf(";", begin);
            if (end == -1) end = dc.length;
            //return json.read(dc.substring(begin, end));
            return JSON.parse(dc.substring(begin, end));
        }
    }
    return null;
}


// Get and set the states of the UI that should be persistent, in the cookie.
// 2nd argument is optional, for UI setting that are lists, e.g. overlayLayers
function getEnfUI (field, subfield) {
    var UIsettings = getCookie('UIsettings');

    if ( arguments.length == 1 ) {
	if (typeof UIsettings[field] !== 'undefined') {
	    return UIsettings[field];
	} else { return null; }
    }

    if ( arguments.length == 2 ) {
	if (typeof UIsettings[field] !== 'undefined') { 
	    if (typeof UIsettings[field][subfield] !== 'undefined') { 
		return UIsettings[field][subfield];
	    } else { return null; }
	} return null;
    }
    console.log("Wrong number of args to getEnfUI");
}


// 3rd argument is optional.  Syntax of 2nd arg is *different* based on number of args;
// The last argument is always the value to be stored
// e.g. setEnfUI('fullScreenP,    true)
// but  setEnfUI('overlayLayers', 'Fuel', true)

function setEnfUI (field, newVal, subVal) {

    // console.log("setEnfUI: " , field , " " , newVal, " ", subVal, " ", arguments.callee.caller);

    var UIsettings = getCookie('UIsettings');

    if ( arguments.length == 2 ) {
	if (typeof UIsettings[field] !== 'undefined') { 
	    UIsettings[field] = newVal; 
	    setCookie('UIsettings', UIsettings);
	    return;
	} return;
    }

    if ( arguments.length == 3 ) {
	if (typeof UIsettings[field] !== 'undefined') { 
	    if (typeof UIsettings[field][newVal] !== 'undefined') { 
		UIsettings[field][newVal] = subVal; 
		setCookie('UIsettings', UIsettings);
		return;
	    } return;
	} return;
    }

    console.log("Wrong number of args to setEnfUI");
}

        
        

// OK.  How big is the goddamn screen?  screen.width and screen.height -- for the hardware screen
// Then, we need the window size (the size of the browser viewport)

// from http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/
function getWindowSize() {
    var viewportwidth;
    var viewportheight;
 
    // the more standards compliant browsers (mozilla/netscape/opera/IE7) use window.innerWidth and window.innerHeight
    if (typeof window.innerWidth != 'undefined') {
	viewportwidth = window.innerWidth,
	    viewportheight = window.innerHeight
	    }
    // IE6 in standards compliant mode (i.e. with a valid doctype as the first line in the document)
    else if (typeof document.documentElement != 'undefined'
	     && typeof document.documentElement.clientWidth !=
	     'undefined' && document.documentElement.clientWidth != 0) {
	viewportwidth = document.documentElement.clientWidth,
	    viewportheight = document.documentElement.clientHeight
	    }
    // older versions of IE
    else {
	viewportwidth = document.getElementsByTagName('body')[0].clientWidth,
	    viewportheight = document.getElementsByTagName('body')[0].clientHeight
	    }
    return [viewportwidth, viewportheight];
}


// console.log("screensize: " + screen.width + " x " + screen.height);
// console.log("window size: " + getWindowSize());


// If theres no already-existing cookie, make a fresh one with default
// settings We will then cache the cookie in this global, so it will be
// preserved while all the openlayers setup happens.  Otherwise, the various
// bits that update the cookie will be turning stuff on and off as part of the
// setup.  We want to ignore that, and reload the cookie only after all that
// has happened.

// Which layers will be on by default.  Maybe only save the ones that are
// true?  This is JSON.
var systemDefaultUIsettings = {
    "baseLayer":          "Sec_TAC_WAC",
    "fullScreenP":        false,
    "gair_show":        [],
    "homeAirport":        "",
    "kneeboardStatus":    'Closed',
    "leftStackStatus":    'Open',
    "leftStackTabOpen":   'CHwin',
    overlayLayers: {
	"Airports":       false,
	"Class_B___C":    false,
	"Forecasts":      true,
	"Fuel":           true,
	"G-Airmet":       false,
	"Prf":            true,
	// ?	"QueryVector Layer": true,
	"RAIM":           false,
	"Radar":          false,
	"Special_Use":    false,
	"TFRs":           true,
	"Victor_Airways_overlay": false,
	"Victor_Airways_base": false,
	"Vors":           false
    },
    "screenSize":     [screen.width, screen.height],    // Hardware screensize
    "windowSize":     getWindowSize(),                  // the window we really have [w, h]
    "zoomLevel":      ""
};


function setupUIcookie () {

    // get the cookie (if there is one)
    UIob = getCookie('UIsettings');

    // if no cookie, then write out the above as the default
    if ( UIob === null ) {
	UIob = systemDefaultUIsettings;
	//	console.log("Resetting UI cookie");

    } else {

	// Grovel over the existing cookie and make sure it has all the same fields as the systemDefaultUIsettings
	for(var field in systemDefaultUIsettings) {
		if ( typeof UIob[field] === 'undefined' ){
		    UIob[field] = systemDefaultUIsettings[field];
		}
	    };

	// Make sure all the overlayLayers are in there too.
	for(var field in systemDefaultUIsettings.overlayLayers) {
		if ( typeof UIob.overlayLayers[field] === 'undefined' ){
		    UIob.overlayLayers[field] = systemDefaultUIsettings.overlayLayers[field];
		}
	    };

	// update the existing one
	UIob.screenSize = [screen.width, screen.height];
	UIob.windowSize = getWindowSize();
    }

    setCookie('UIsettings', UIob);  // This has the side-effect of updating the expires-time
}

function getIEVersion()
// Returns the version of Internet Explorer or a -1
// (indicating the use of another browser).
{
    var rv = -1; // Return value assumes failure.
    if (navigator.appName == 'Microsoft Internet Explorer') {
	    var ua = navigator.userAgent;
	    var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
	    if (re.exec(ua) != null)
		rv = parseFloat( RegExp.$1 );
	}
    return rv;
}

// This is called in-line, so we're guaranteed to have a UISettings
// cookie by the time this file (enf.js) finishes loading.

setupUIcookie();

