/* ---------------------------------------------------------- */
/* Debug Functions										      */
/* ---------------------------------------------------------- */

function log(message) {
	if ( window.console != null ) window.console.log(message);
}

function TimeSample() {
	this.timesample_start = (new Date()).getTime();
	this.global_start = this.timesample_start;
	return this;
}
TimeSample.prototype.sample = function sample(comment) {
	var current_time = (new Date()).getTime();
	if ( comment ) log( ((current_time - this.global_start) / 1000) + 's - ' + ((current_time - this.timesample_start) / 1000) + 's: ' + comment );
	this.timesample_start = current_time;
}

var timeSample = new TimeSample();

/* ---------------------------------------------------------- */
/* Browser Detector										      */
/* ---------------------------------------------------------- */

var BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || 'An unknown browser';
		this.version = this.searchVersion(navigator.userAgent) || this.searchVersion(navigator.appVersion) || 'an unknown version';
		this.OS = this.searchString(this.dataOS) || 'an unknown OS';
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
	{string: navigator.userAgent, subString: 'OmniWeb', versionSearch: 'OmniWeb/', identity: 'OmniWeb'},
	{string: navigator.vendor,subString: 'Apple',identity: 'Safari'	},
	{prop: window.opera,identity: 'Opera'},
	{string: navigator.vendor,subString: 'iCab',identity: 'iCab'},
	{string: navigator.vendor,subString: 'KDE',identity: 'Konqueror'},
	{string: navigator.userAgent,subString: 'Firefox',identity: 'Firefox'},
	{string: navigator.vendor,subString: 'Camino',identity: 'Camino'},
	// for newer Netscapes (6+)
	{string: navigator.userAgent,subString: 'Netscape',identity: 'Netscape'},
	{string: navigator.userAgent,subString: 'MSIE',identity: 'Explorer',versionSearch: 'MSIE'},
	{string: navigator.userAgent,subString: 'Gecko',identity: 'Mozilla',versionSearch: 'rv'	},
	// for older Netscapes (4-)
	{string: navigator.userAgent,subString: 'Mozilla',	identity: 'Netscape',versionSearch: 'Mozilla' } 
	],
	dataOS : [
	{string: navigator.platform,subString: 'Win',identity: 'Windows'},
	{string: navigator.platform,subString: 'Mac',identity: 'Mac'},
	{string: navigator.platform,subString: 'Linux',	identity: 'Linux'}
	]

};

BrowserDetect.init();

/* ---------------------------------------------------------- */
/* Generic Functions										  */
/* ---------------------------------------------------------- */

function swallowEvent(e) {
	if (e === undefined || !e)
		var e = window.event;
	if ( e != undefined ) {
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	}
}

function dget(identifier) {
	return document.getElementById(identifier);
}

function toggleDisplay(element) {
	element.style.display = (element.style.display == 'none') ? 'block' : 'none';
}
function toggleVisibility(element) {
	element.style.visible = (element.style.display == 'hidden') ? 'visible' : 'hidden';
}
function setCSSClass(element,className) {
	element.setAttribute((document.all ? 'className' : 'class'), className);
}

function randomNumber(max) {
	return Math.floor(Math.random()*(max+1));
}

function whichElement(event) {
	// From Prototype framework. The function return the element that receive the action
	return Event.element(event);
}

function removeAllChildren(element) {
	if (element == null) return;
	while ( element.hasChildNodes() ) element.removeChild(element.lastChild);
}

function removeAllChildrenById(identifier) {
	removeAllChildren(dget(identifier));
}

function confirmation(message) {
	return confirm(message);
}

function findAbsolutePosition(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		do {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		} while (obj = obj.offsetParent);
	}
	return [curleft,curtop];
}

/* ---------------------------------------------------------- */
/* Focus Tracking                                             */
/* ---------------------------------------------------------- */

var currentFocus = '';

if (document.getElementsByTagName) onload = function () {
	var e, i = 0;
	while (e = document.getElementsByTagName('INPUT')[i++]) {
		if (e.type == 'text') {
			e.onfocus = function () {
				currentFocus = this;
			}
			e.onblur = function () {
				currentFocus = '';
			}
		}
	}
}


/* ---------------------------------------------------------- */
/* Keyboard Interation / Manager							  */
/* ---------------------------------------------------------- */

function KeyboardManager() {

	// Build an array of handlers
	this.observers = new Array();

	// Register for keyboard events
	document.onkeyup = this.keyCheck;
	document.onkeydown = this.updateKeysFromEvent;

	// Flags for modifier keys
	this.altKey = false;
	this.shiftKey = false;
	this.ctrlKey = false;
	this.metaKey = false;

	return this;
}

KeyboardManager.prototype.registerAsObserverForKey = function(observer,key) {
	var i = parseInt(key);
	if ( this.observers[i] === undefined )
		this.observers[i] = new Array(observer);
	else
		this.observers[i].push(observer);
}

KeyboardManager.prototype.registerAsObserverForAllKeys = function(observer) {
	this.registerAsObserverForKey(observer,0);
}

KeyboardManager.prototype.keyCheck = function(e) {

	keyboardManager.updateKeysFromEvent(e);

	var keyID = parseInt( (window.event) ? event.keyCode : e.keyCode );

	if ( keyboardManager.observers[keyID] !== undefined )
		for ( var i = 0; i < keyboardManager.observers[keyID].length; i++ )
			keyboardManager.observers[keyID][i](keyID);

	if ( keyboardManager.observers[0] !== undefined )
		for ( var i = 0; i < keyboardManager.observers[0].length; i++ )
			keyboardManager.observers[0][i](keyID);

}

KeyboardManager.prototype.updateKeysFromEvent = function(e) {
	e = (e) ? e : (window.event) ? window.event : '';
	if (e) {
        var elem = (e.target) ? e.target : e.srcElement
        var form = document.output
        if (e.modifiers) {
        	this.altKey = e.modifiers & Event.ALT_MASK;
    		this.shiftKey = e.modifiers & Event.SHIFT_MASK;
    		this.ctrlKey =  e.modifiers & Event.CONTROL_MASK;
    		this.metaKey = e.modifiers & Event.META_MASK;
        } else {
        	this.altKey = e.altKey;
    		this.shiftKey = e.shiftKey;
    		this.ctrlKey = e.ctrlKey;
    		this.metaKey = e.metaKey;
        }
    }
}

// Instantiate singleton
var keyboardManager = new KeyboardManager();

/* ---------------------------------------------------------- */
/* Style Functions   										  */
/* ---------------------------------------------------------- */

// This array is used only for IE6 client
var tmpStyle = Array();

// Function for search class in stylesheet.
// Return the propreties of class
// Option value is the name of css file, so research is only in this file
function getStyleClass (className, cssFileName) {
  // var re = new RegExp(className + '$', 'g');
  var re = new RegExp(className);
  var cssName = new RegExp(cssFileName);

  if (document.all) {
    for (var s = 0; s < document.styleSheets.length; s++){
		if ( cssName!= '' && document.styleSheets[s].href.search(cssName) != -1 )
			for (var r = 0; r < document.styleSheets[s].rules.length; r++){
				if (document.styleSheets[s].rules[r].selectorText.search(re)!= -1)
					return document.styleSheets[s].rules[r].style.cssText;
			}
		}
	}
	else if (document.getElementById) {
		for (var s = 0; s < document.styleSheets.length; s++)
			for (var r = 0; r < document.styleSheets[s].cssRules.length; r++)
			if (document.styleSheets[s].cssRules[r].selectorText.search(re) != -1) {
			document.styleSheets[s].cssRules[r].sheetIndex = s;
			document.styleSheets[s].cssRules[r].ruleIndex = s;
			return document.styleSheets[s].cssRules[r].style;
			}
	}
	else if (document.layers)
		return document.classes[className].all;

  return null;
}

// Function for get propertyName from css class
function getStyleClassProperty (className, propertyName) {
  var styleClass = getStyleClass(className);
  if (styleClass)
    return styleClass[propertyName];
  else
    return null;
}

// Generic function to translate a css class definition in inline STYLE
function trasformCssToinlineStyle(pageDiv, css){
	for (i=0; i<pageDiv.length; i++){
		currentDiv = pageDiv[i];
		div = dget(currentDiv);
		if (div != null){
			divClassName =  div.className+'.'+currentDiv;
			inlineStyle = getStyleClass(divClassName, css);
			if (tmpStyle[currentDiv]) inlineStyle = inlineStyle+''+tmpStyle[currentDiv];
			//alert ("div="+pageDiv[i]+" class="+div.className+" style= "+inlineStyle+"");
			this.div.style.setAttribute('cssText',inlineStyle);
		}
	}
}

/* ---------------------------------------------------------- */
/* String Buffer Implementation								  */
/* ---------------------------------------------------------- */

function StringBuffer() {
	this.buffer = [];
}

StringBuffer.prototype.append = function append(string) {
	this.buffer.push(string);
	return this;
}

StringBuffer.prototype.mappend = function mappend() {
	var operands = this.mappend.arguments;
	var z = 0;
	do {
		this.buffer.push(operands[z++]);
	} while (z<(operands.length));
	return this;
}

StringBuffer.prototype.toString = function toString() {
	return this.buffer.join('');
}

/* ---------------------------------------------------------- */
/* Cookie Functions											  */
/* ---------------------------------------------------------- */

function loadCookies() {
	var cookie;

	// Load the palette cookie
	cookie= readCookie('SW2-PaletteSnapshot');
	if ( cookie != null && cookie != '.') palettes.setSnapshot(cookie);

}

function feedCookies() {
	// Create a cookie to hold palette data
	var pgs = palettes.snapshot();

	// log("Feeding cookie " + pgs);
	createCookie('SW2-PaletteSnapshot', ((pgs != null && pgs.length > 0) ? pgs : '.'), 10);
}


function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = '; expires='+date.toGMTString();
	}
	else var expires = '';
	document.cookie = name+'='+value+expires+'; path=/';
}

function readCookie(name) {
	var nameEQ = name + '=';
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name,'',-1);
}

/* ---------------------------------------------------------- */
/* Double & Triple Click Functions											  */
/* ---------------------------------------------------------- */

var multiClicker = new MultiClicker();

function MultiClicker() {
	this.recentlyClicked = null;
	this.recentlyDoubleClicked = null;
	this.doubleClickTimeout = null;
	this.doubleClickTimeoutDuration = 1000;
	this.tripleClickTimeout = null;
	this.tripleClickTimeoutDuration = 300;
	return this;
}

MultiClicker.prototype.doubleClick = function(clicked) {
	if ( (this.recentlyClicked == null) || (clicked.id != this.recentlyClicked.id) ) {
		log('SINGLE');
		this.recentlyClicked = clicked;
		this.doubleClickTimeout = setTimeout('multiClicker.recentlyClicked = null;',this.doubleClickTimeoutDuration);
		return false;
	}
	this.recentlyDoubleClicked = this.recentlyClicked;
	this.tripleClickTimeout = setTimeout('multiClicker.recentlyDoubleClicked = null;',this.tripleClickTimeoutDuration);
	this.recentlyClicked = null;
	log('DOUBLE');
	return true;
}

MultiClicker.prototype.tripleClick = function(clicked) {
	this.doubleClick(clicked);
	return this.recentlyDoubleClicked == clicked;
}


/* ---------------------------------------------------------- */
/* Pinger Functions											  */
/* ---------------------------------------------------------- */

var pinger = new Pinger();

function Pinger() {
	this.timeoutInterval = parseInt(3);
	this.timeoutIncrease = parseInt(1);
	this.timeoutMax = parseInt(60);
	this.timeout = null;
	this.sample = parseInt(0);
	this.slowPing = parseInt(20);
	this.fastPing = parseInt(3);
	this.currentMode = 0;
	this.previousFailed = false;
	return this;
}

Pinger.prototype.start = function _Pinger_start() {
	this.timeout = setTimeout('pinger.ping();', (this.timeoutInterval * 1000) );
}

Pinger.prototype.stop = function _Pinger_stop() {
	clearTimeout(this.timeout);
}

Pinger.prototype.slow = function _Pinger_slow() {
	this.timeoutInterval = this.slowPing;
	this.currentMode = 0;
}

Pinger.prototype.fast = function _Pinger_fast() {
	this.timeoutInterval = this.fastPing;
	this.currentMode = 1;
}

Pinger.prototype.ping = function _Pinger_ping() {

	if ( this.previousFailed ) {
		dget('lastpingstats').innerHTML = 'ND';
		dget('refreshfrequency').innerHTML = this.timeoutInterval;
	} else {
		switch ( this.currentMode ) {
			case 0: {
				this.slow();
				break;
			}
			case 1: {
				this.fast();
				break;
			}
		}
	}

	// Set this flag to false so that if we don't get a positive answer from the server, next time we can update the flags
	this.previousFailed = true;

	// Get the current time
	var ts = (new Date()).getTime();

	// Clear the old timeout is it still exists
	clearTimeout(this.timeout);

	// setup a new timeout to a value greater than the previous by timeoutIncrease up to a maximum of timeoutMax
	// if the server doesn't reply with a new timeout value, we alredy have this setup
	var toi = parseInt(this.timeoutInterval);
	var toii = toi + this.timeoutIncrease;

	if ( toii > this.timeoutMax ) toii = this.timeoutMax;
	this.timeout = setTimeout('pinger.ping();', (toii * 1000) );

	// set this.timeoutInterval to toii just in case we don't get an answer from the server
	this.timeoutInterval = toii;

	// Ping the server with the value of the next timeout
	var pingReply = mejason.wopage.ping(toi, parseInt(this.sample) );

	// Sample the time now and figure out how much it took
	this.sample = ((new Date()).getTime()) - ts;

	// The first item of the ping reply is the next timeout
	if ( pingReply[0] > 0 ) {

		this.previousFailed = false;

		// we got server reply so fix back out timoutinterval to what was before
		this.timeoutInterval = parseInt(pingReply[0]);

		// clear the default timeout
		clearTimeout(this.timeout);

		// build a new one following the server advice
		this.timeout = setTimeout('pinger.ping();', ( this.timeoutInterval * 1000) );
	}

	dget('lastpingstats').innerHTML = this.sample/1000;
	dget('refreshfrequency').innerHTML = this.timeoutInterval;

	// The second element of pingReply is the event queue to be processed
	var events = pingReply[1];
	if ( events != null ) {
		var count = events.length;
		for (var index = 0; index < count; index++) {
			this.processEvent(events[index]);
		}
	}

}

Pinger.prototype.processEvent = function _Pinger_processEvent(event) {

	// An event is an array.
	// The first element is the event type.
	// The rest is undefined and can vary from event type to event type.

	//var event = e[0];
	if  (event == null) return;

	var type = event[0];
	if  (type == null || type == '') return;

	// log("Processing event type " + type);

	if ( type[0] == 'C' ) {
		comunityPaletteProcessEvent(event);
	}
}

/* ---------------------------------------------------------- */
/* Supersleight script courtesy of Drew McLellan			  */
/* http://24ways.org/2007/supersleight-transparent-png-in-ie6 */
/* ---------------------------------------------------------- */

var supersleight = function() {
	
	var root = false;
	var applyPositioning = true;

	// Path to a transparent GIF image
	var shim = '/WebObjects/Frameworks/TFramework.framework/WebServerResources/x.gif';
	
	// RegExp to match above GIF image name
	var shim_pattern = /x\.gif$/i;

	var fnLoadPngs = function() { 
		if (root)
			root = document.getElementById(root);
		else
			root = document;

		for (var i = root.all.length - 1, obj = null; (obj = root.all[i]); i--) {
			// background pngs
			if (obj.currentStyle.backgroundImage.match(/\.png/i) !== null)
				bg_fnFixPng(obj);

			// image elements
			if (obj.tagName=='IMG' && obj.src.match(/\.png$/i) !== null)
				el_fnFixPng(obj);
		
				
			// apply position to 'active' elements
			if (applyPositioning && (obj.tagName=='A' || obj.tagName=='INPUT') && obj.style.position === '')
				obj.style.position = 'relative';
		}
	};

	var bg_fnFixPng = function(obj) {
		var mode = 'scale';
		var bg	= obj.currentStyle.backgroundImage;
		var src = bg.substring(5,bg.length-2);
		if (obj.currentStyle.backgroundRepeat == 'no-repeat')
			mode = 'crop';
		obj.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + src + '\', sizingMethod=\'' + mode + '\')';
		obj.style.backgroundImage = 'url('+shim+')';
	};

	var el_fnFixPng = function(img) {
		var src = img.src;
		img.style.width = img.width + 'px';
		img.style.height = img.height + 'px';
		img.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + src + '\', sizingMethod=\'scale\')';
		img.src = shim;
	};
	
	var addLoadEvent = function(func) {
		var oldonload = window.onload;
		if ( typeof window.onload != 'function')
			window.onload = func;
		else {
			window.onload = function() {
				if (oldonload) oldonload();
				func();
			};
		}
	};
	
	return {
		init: function() { 
			addLoadEvent(fnLoadPngs);
		},
		limitTo: function(el) {
			root = el;
		},
		run: function() {
			fnLoadPngs();
		}
	};
}();

// limit to part of the page ... pass an ID to limitTo:
// supersleight.limitTo('header');

// Init stuff...

//Patch PNG problems if browser is IE6
if ( BrowserDetect.browser == 'Explorer' && BrowserDetect.version < '7' )
	supersleight.init();

// Replace all classes with inline styles if browser is IE6
/*if ( BrowserDetect.browser == 'Explorer' && BrowserDetect.version < '7' ){
	var pageDiv = Array('htmlbody');
	trasformCssToinlineStyle(pageDiv, "MainEnclosure.css");
}*/

