/*!require: JAME */

/*
Title: JAME Javscript Animation Made Easy

package: JAME

	The Base JAME.js files contains all the functions related to creating namespaces.

	It also contains some basic helper like warn, extend,each.


	By using namespacing functionalities you will avoid conflict with other scripts.


	Sticking to one and unique namespace is best and can improve performance when looking up for functions.

	All the functions/classes of JAME are in the... 

	wait for it...

	JAME 

	namespace.

	I hear some of you saying...

	'JAME'? 4 letters? Too much typing!


	The fluent API offers the $J namespace that you can shorten even more to $ = $J if you want.
	
	If you do not want to use the fluent API, just alias the JAME variable...

	var flowerpower = JAME.

	well...

	As you can see, my naming skills need some training... 

	
	Anyhow!:

	Speech-less, code more.

    Here is a little example based on the JAME.Util.String package.

	It shows how to use some of the functions defined within this package.

	First we define a package of our own and see how we can use it.

Example:

	(start code)
    //package example


	//create your namespace
	JAME.Package("JAME.Toolbox.Strings");

	//define its content
	JAME.Toolbox.Strings = {
		firstToUpperCase : function (str) {
			return str.replace(/^[a-z]/,function(m,l) { 
                      return l.toUpperCase() } 
            );
		},
		_privateMethod : function (str) { //private method not exported
            //calculation here
		},
        myPublicMethod : function (str) {
			str = split('',str);
			return _privateMethod(str);
		},
         Export : function() {
			//export firstToUppercase, myPublicMethod
			JAME.Exporter(JAME.Toolbox.Strings); 
			//or export just JTSfirstToUpperCase
			//JAME.Exporter({"JTSfirstToUppercase":JAME.Toolbox.Strings.firstToUpperCase});
		}
	};
       
       // user code


        //nothing imported
        JAME.Toolbox.Strings.firstToUpperCase(str);


        //import everything from the package to the global space
	 JAME.Import(JAME.Toolbox.Strings); //or JAME.Import("JAME.Toolbox.Strings");
	 firstToUpperCase(str);
       

        //alias the package 
        var JS=JAME.Toolbox.Strings;
	 JS.firstToUpperCase(str);

	(end)

*/


JAME = {

	VERSION:0.01,

	__DUMMY_FUNCTION:function(){},

	//chicken egg problem with the JAME.Data namespace...
	//could have defined the Data object with this set of functions
	//but its a little bit heavy...
	_isObject : function(obj){
		if(obj===undefined) return undefined;
		if(obj.constructor===Object)
			return 1;
		return undefined;
	},
/*
Function: warn

	Log a message to the console if any.

	The message will also display the stack trace based on the trace level set.

Parameters:

    sErrorMessage  - the message to be logged.
	iTraceLevel    - the stack trace level, by default 0 (wich means one level up)
				    if you set -1, the entire stack trace will be output to the console


Returns:
	void.
*/
    warn : function (sErrorMessage,iTraceLevel) { 
		var level  = iTraceLevel || 0;
		var caller = arguments.callee.caller;
		var _level = 0;
		while (caller && caller.caller && caller != caller.caller) {
			caller = caller.caller || caller;
			if(_level==level)
				break;
			_level++;
		}

		if ("console" in window)
  			console.warn(sErrorMessage+caller);
		else 
			JAME.warn=JAME.__DUMMY_FUNCTION;
	},
/*
about: Example
	>function stringToArray(str) {
	>	if(!str){
	>		JAME.warn("you must provide a String Object",-1);
	>		return;
	>	}
	>	//implementation goes here
	>}
*/

/*
Function: extend
	Allow to extend the properties/functions of a namespace/class/object with an other

Parameters:
	oDestination - the object that will be extended.
	oSource      - the object that will extend the destination
	bOverwrite   - shall will erase conflicting functions/properties or not
				 (default: false)

Returns:
	void.

*/
	extend : function(oDestination, oSource,bOverwrite) {
		bOverwrite = bOverwrite || false;
		if(!JAME._isObject(oDestination) && !JAME._isObject(oSource)){
			JAME.warn("arguments must be Objects...");
			return;
		}
    	for (var element in oSource) {
        	if(typeof oDestination[element] == "undefined") {
           		oDestination[element] = oSource[element];
        	}
			else if(oDestination[element] && !bOverwrite){
           		oDestination[element] = oSource[element];
			}
    	}
	}
/*
about: Example
	>//extend JAME.FX with an other object
	>JAME.extend(JAME.FX.prototype,new JAME.Events.EventDispatcher):

	
	JAME.FX can now calls the dispatch method from <JAME.Events.EventDispatcher>
*/


};

JAME.Data = {

	_isNumber : function(str){
		if(str===undefined) return undefined;
		if(str.constructor===Number)
			return 1;
		return undefined;
	},

	_isString : function(str){
		if(str===undefined) return undefined;
		if(str.constructor===String)
			return 1;
		return undefined;
	},

	_isArray : function(ar){
		if(ar===undefined) return undefined;
		if(ar.constructor===Array)
			return 1;
		return undefined;
	},

	//for consistency sake...
	_isObject : JAME._isObject,

	_isList : function(col){
		if(col===undefined) return undefined;
		//basic duck typing because IE sucks...
		//NodeList
		if(col.length && col.item)
			return 1;
		//arguments
		if(col.length && col.callee)
			return 1;
		return undefined;
	},

	_toArray : function(elm) {

		if(JAME.Data._isEmpty(elm)){
			return [];
		}
		else if(JAME.Data._isString(elm)){
			return elm.split("");
		}
		else if(JAME.Data._isArray(elm)){
			return elm;
		}
		else if(JAME.Data._isList(elm)){
			var ret = [];
			for(var i=0,ln=elm.length;i<ln;i++){
				ret[i]=elm[i];
			}
			return ret;
		}
		else {
			JAME.warn("argument is not one of the supported format. returning empty array.");
			return [];
		}

	},

	_isEmpty : function(elm) {
		if(elm===undefined){
			return 1;
		}
		if(JAME.Data._isString(elm) && elm.split("").length===0){
			return 1;
		}
		else if(JAME.Data._isArray(elm)&& elm.length===0){
			return 1;
		}
		else if(JAME.Data._isList(elm)) {
			return (elm.length===0) ? 1 : undefined;
		}
		else if(JAME.Data._isObject(elm)){
			for(props in elm)
				return undefined;
			return 1;
		}
		return undefined;	
	}
};

JAME.extend(JAME, {
/*
Function: $
	get an HTML Element by its id. 

	Alias for document.getElementsById().

	IE might send back an element which name attribute is equal to the id. 
	$ will warn and try to find the proper element or return undefined.

Parameters:
	sElementId  - id name of an HTMLElement.

Returns:
	HTMLElement if found or undefined otherwise.

*/
	$ : function(sElementId) {



		var d  = document;
		if(d && d.getElementById) {

			var holder = (d.all) ? function(id) {
				var ret = d.getElementById(id);
				if(ret && ret.attributes['id'] && ret.attributes['id'].value===id) {
					return ret;
				}
				else {	

					var all=d.all;
					if(!all[id]) return undefined;
 					for(var i=1,ln=all[id].length;i<ln;i++){
						var elm=all[id][i].attributes['id'];
          				if(elm && elm.value === id){
            				return all[id][i];
         				 }
       				 }
				}
				return undefined;
			} : function(id) {
					return document.getElementById(id)? document.getElementById(id):undefined;
			};

			JAME.$=holder;
			return holder(sElementId);
		}
		return undefined;
	},
/*
about: Example
	>var elm = JAME.$("myId"):

*/

/*
Function: each
	iterate other an array and apply a function to each element

Parameters:
	aElm      - the array to iterate over or a HTML nodeList/arguments.
	fCallback - the callback will get the element, the iteration number and the entire array

Example:
	> var ar = JAME.each([1,2,3],function(elm,i,entries){
	>		entries[i]=elm+i;
	> });
	> alert(ar) //output should be [1,3,5]

Returns:
	the array (useful when you feed the function with a nodeList or an arguments object)

*/

	each : function(elm,fn){
		
    	for(var i=0,ln=elm.length;i <ln ;i++) 
            fn.apply(Array,[elm[i],i,elm]);
		return elm;
	},
/*
Function: Package
	Create a namespace.

	The On-Demand Downloader will decompose namespaces by changing dots into slashes
	and add the js extension to the final namespace:
	JAME.FX.CSS.Colors
	will be understood as
	JAME/FX/CSS/Colors.js

Arguments:
	sName - the namespace delimited by dots.

Example:
	>JAME.Package("JAME.FX.CSS.Colors");
	>JAME.FX.CSS.Colors = { ... };

Returns:
	void
*/
	Package : function (sname) {


		//split the name by dots
    	var namespaces=sname.split('.') || [sname];
    	var nlen=namespaces.length;
	
    	var root = window;
    	var F    = JAME.__DUMMY_FUNCTION;

    	for(var i=0;i<nlen;i++) {
        	var ns = namespaces[i];
        	if(typeof(root[ns])==='undefined') {
            	root = root[ns] = F;
            	root = root.prototype = F;
        	}
        	else
           		root = root[ns];
    	}
		return root;
	},
/*
Function: Import
	Import into the global namespace package functions or variables.

Arguments:
	oNames - the namespaces to import.
	alternative:
	sNames - the namespaces to import: as the string will be converted to an object, it incurs some overhead

Example:
	>JAME.Import(JAME.DOM , JAME.FX.Transition , JAME.Util.String);

Returns:
	void.

See Also:

      <JAME.Exporter> , <JAME.Export>
*/

	Import : function () {
		var nlen=arguments.length;
		for(var i=0;i<nlen;i++) {
			var pk=arguments[i];
			pk = (pk && pk.constructor===String) ? JAME.Package(pk):pk;
			if(pk.Export!==undefined) {
				pk.Export();
        	}
			else if (pk.prototype && pk.prototype.Export!==undefined) {
				pk.prototype.Export();
			}
			else {

			}
		}
	},

/*
Function: Exporter
	Define methods, variables importable into the global namespace.

	All methods, variables starting with '_'  are considered private and won't be exported.

	This is just a convention, you can always use anonymous functions to create real private methods.


Arguments:
	oName - key : value pair where the key is the original namespace and value the exported name.

Example:
	>JAME.Exporter({ "JAME.Package" : "Package", "JAME.Import" : "Import"});
	>//or in order to export everything:
	>JAME.Exporter(this);


Returns:
	void.

See also:
	<JAME.Export>
*/

	Exporter : function (oName,sPref) {
		if(!sPref) {
			sPref='';
		}
		else {

		}

		for(var method in oName) {
	    	if(method==="Export" || /^_/.test(method)) continue;
	    	window[sPref+method]=oName[method];
    	}
	},
/*
Function: Export
	Call by <JAME.Import>

	Shoud be implemented by all packages that allow 

	the export of their methods/properties to the global namespace.

	the Export function itself just calls JAME.Exporter method and defines

	the function to be exported and their names

Arguments:
	none.

Example:
	>//allow to export a set of functions
	>JAME.Export = function () {
	>JAME.Exporter({ "JPackage" : JAME.Package, "JImport" : JAME.Import});
	>}
	>//allow to export all functions
	>JAME.Export = function () {
	>JAME.Exporter(JAME);
	>}

Returns:
	void.

See also:
	<JAME.Exporter>
*/
	Export : function () {
		JAME.Exporter({ "Package" : JAME.Package, "Import" : JAME.Import});
	}
});
/*!require: JAME */
JAME.Package('JAME.Events');

JAME.Events =  {
	
	Normalize : function(event) {

    	event = event || window.event;

    	if(window.event) {

        	event.preventDefault = function() {
             	this.returnValue= false;
        	};
        	event.stopPropagation = function() {
            	this.cancelBubble = true;
        	};
        	event.target = event.srcElement;       

        	event.relatedTarget = (event.fromElement == event.target) 
                                ? event.toElement 
                                : event.fromElement;
    	}
		if(!event.target) return event;
    	if (event.target.nodeType == 3) event.target = event.target.parentNode;

    	if ( event.pageX == null && event.clientX != null ) {
        	var e = document.documentElement, b = document.body;
        	event.pageX = event.clientX + (e && e.scrollLeft || b.scrollLeft || 0);
        	event.pageY = event.clientY + (e && e.scrollTop || b.scrollTop || 0);    
    	}

    	if ( event.layerX == null && event.offsetX != null ) {
        	event.layerX = event.offsetX || 0;
        	event.layerY = event.offsetY || 0;
    	}

    	if ( !event.which && (event.charCode || event.keyCode) )
      		event.which = event.charCode || event.keyCode;
    
    	if ( !event.metaKey && event.ctrlKey )
      		event.metaKey = event.ctrlKey;

    	if ( !event.which && event.button )
      		event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
      
    	return event;
	},
	
	addListener : function (elm,evt, func,bind) {

		if (!elm.listeners) elm.listeners = {};

		if (!elm.listeners[evt]) elm.listeners[evt] = [];

		for(var i=0;i<elm.listeners[evt].length;i++){
			if(elm.listeners[evt][i]===func) {
				JAME.warn('the same event '+evt+' is set for '+elm+' ',-1);
				return false;
			}
		}
		elm.listeners[evt].push(func);
		if(bind===undefined)
			func.____willBindTo=elm;
		else 
			func.____willBindTo=bind;

		if(!window.attachEvent)
			evt = (evt=='mouseenter')?'mouseover':(evt=='mouseleave')?'mouseout':evt;	
		elm["on" + evt] = JAME.Events._handleEvent;
		return elm;
	},

	_isChild : function(parent,child) {
		if(parent === child) return false;

		while (child && child!==parent)
			child= child.parentNode;
		return child===parent;
	},

	_handleLeaveEnterEvent : function (evt) {

		var relatedTarget = evt.relatedTarget;

		if(this ===relatedTarget || JAME.Events._isChild(this,relatedTarget)) return;

		var listeners = this.listeners[evt.type=='mouseover'?'mouseenter':'mouseleave'];
		var ln     = listeners.length;
		var ret;
		for (var i=0; i<ln; i++) {
			ret = listeners[i].call(listeners[i].____willBindTo, evt);
			if (i === (ln - 1))
				return ret;
		}
	},

	_handleEvent : function (evt) {

		evt = JAME.Events.Normalize(evt);

		if(evt.type=='mouseover' && !window.attachEvent && this.listeners['mouseenter']){
			JAME.Events._handleLeaveEnterEvent.call(this,evt);
		}
		if(evt.type=='mouseout' && !window.attachEvent && this.listeners['mouseleave']){
			JAME.Events._handleLeaveEnterEvent.call(this,evt);
		}

		var listeners = this.listeners[evt.type];
		if(!listeners) return;
		var ln     = listeners.length;

		var ret;
		for (var i=0; i<ln; i++) {
			ret = listeners[i].call(listeners[i].____willBindTo, evt);
			if (i === (ln - 1))
				return ret;
		}

	},
	removeListener : function (elm,evt, func) {
		if(!elm) return;
		if(!evt) return;
		if(!elm.listeners) return;
		var listeners = elm.listeners[evt];
		if(!listeners) return;
		if(!func) 
			return JAME.Events.removeListeners(elm,[evt]);
		var ln = listeners.length;
		for (var i=0; i<ln; i++) {
			if (listeners[i] === func) {
				//avoid leaks
				//if(func.____willBindTo) func.____willBindTo=null;
				delete listeners[i];
				listeners.splice(i, 1);
			}
		}
		return true;
	},
	removeListeners : function (elm,evts) {
		evts = (evts.constructor===Array) ?evts :[evts];
		for(var i=0,ln=evts.length;i<ln;i++)
			elm.listeners[evts[i]]=[];
		return true;
	}
};


/*
Title: JAME Javscript Animation Made Easy

package: JAME.Events

		fix browser incompatibilities

base: JAME

	<JAME>

package: JAME.Events.EventDispatcher

    offer observer based functionalities to your class (dispath,remove,listen)

	By using this class, your own class can create custom events and dispatch them to the listeners.

base: JAME JAME.Events

    <JAME>
    <JAME.Events>
	

Todo:
	- the class structure is dubious: rewrite in a more logical relationship
	- add data validation and related warnings!
	- verify that the example is right!

Example:

	(start code)

		//class usage

		function MyClass () {}

		JAME.Extend(myClass.prototype,new JAME.Events.EventDispatcher());

		myClass.prototype= {
			val1 : 0,
			init : function () {
				this.dispatch('onInit');
			},
			loaded : function () {
				this.dispatch('onLoaded');
			},
		}

		//end user usage

		var myclass= new MyClass();
			myclass.val1=1;
		myclass.addListener('onLoaded',function(){alert(this.val1)});
		myclass.init();
		

	(end)


constructor: JAME.Events.EventDispatcher
	instantiate the class
	

Arguments:
	none

Example:
	>var dispatcher = new JAME.Events.EventDispatcher();

Returns:
	JAME.Events.EventDispatcher object

Section: Methods

method: dispatch
	allow to dispatch an event from within your class
	the listeners will get the dispatcher object (or the one it is used in) as the this object
	
Arguments:
	sEventName : the event name you want to dispatch
	arguments  : whatever parameters you want to send to the listeners

Example:

	(start code)

		this.dispatch('onInit',val1,val2);

	(end)

Returns:
	void


method: addListener
	allow to listen to a custom event dispatched by an object
	

Arguments:
	sEventName : the event name you want to listen to
	fcallback  : the function to execute

Example:

	(start code)

		JAME.Events.addListener(JAME.$('container'),'mouseenter',function(evt,ret) {
			this.innerHTML=ret;
		});

		JAME.Events.addListener(JAME.$('container'),'mouseenter',function(evt,ret) {
			var target = evt.target;
			target.innerHTML=ret;
		},false);

	(end)

Returns:
	void



method: removeListener
	allow to remove a listener from an elements
	

Arguments:
	sEventName : the event name you want to listen to
	fcallback  : the function to remove

Example:

	(start code)
		function myCallbackFunction1 (e){
			alert(1);
		}
		function myCallbackFunction2 (e){
			alert(2);
		}
		function myCallbackFunction3 (e){
			alert(3);
		}
		//remove myCallbackFunction1 only
		myeventdispatcher.removeListener('onInit',myCallbackFunction1);

		//remove all listeners that are still attached, here myCallbackFunction2 & myCallbackFunction3
		myeventdispatcher.removeListener('onInit');
	(end)

Returns:
	void

Section: Exported functions

	none

*/



JAME.Events.EventDispatcher = function() {this.listeners = {}};

JAME.Events.EventDispatcher.prototype = {
    dispatch : function(evt) {
        var listeners = (this.listeners[evt]) ?this.listeners[evt].length : 0;
        for(var i=0;i<listeners;i++)
            this.listeners[evt][i].apply(this,arguments);
        return this;
    },
    addListener : function (evt,func) {
        if(!this.listeners[evt]) this.listeners[evt]=[];
        this.listeners[evt].push(func);
    },
    removeListener : function (evt,func) {
		JAME.Events.removeListener(this,evt,func);
    }
};



/*!require: JAME,JAME.Events */
JAME.Package('JAME.DOM');
JAME.Package('JAME.__STORE__');

new function() {

 var store      = {};
 JAME.__STORE__ = {
	add : function(elm,key,val) {
		if(!store[elm]){
			store[elm]={};
		}
		store[elm][key]=val;	
	},
	remove : function(elm,key) {
		if(store[elm] && store[elm][key]){
			store[elm][key]=null;
			delete store[elm][key];
		}	
	},
	get : function(elm,key) {
		if(!store[elm])
			return undefined;
		return store[elm][key];
	},
	removeAll : function(elm){
		if(store[elm]){
			for(var prop in store[elm]){
				store[elm][prop]=null;
				delete store[elm][prop];
			}
		}		
	},
	cleanup : function() {
		for(var obj in store){
			JAME.__STORE__.removeAll(obj);
		}
		store=null;
	}
 };

}


/*
Title: JAME.DOM - DOOM as never been that fun

Script: Manipulation.js
	JAME.DOM - Cross browsers function to traverse, manipulate the DOM

Section: Dependency

    <JAME.js>

	<JAME.EventDispatcher>


About:
	Version 0.01

License:
	MIT-style license.

Credits:
       - inspired by Mootools, Jquery,Protoype and the community.


Example:

	(start code)

	JAME.DOM.Ready(function() {
		if(JAME.DOM.hasClass(JAME.$('title'),'selected')){
			JAME.$('title').innerHTML+=' SELECTED';
		}
	})

	(end)

Section: DOM traversing related functions

Function: JAME.DOM.lastNode

	Get the last node of a section


Arguments:
	oHTMLElement - an HTML object 

Example:
	>JAME.DOM.lastNode(JAME.$("contents"));
	
	><div id="contents">
	><h2>My contents</h2>
	><p>My paragraph 1</p>
	></div>
    >//will return the html object,p, containing My paragraph 1

Returns:
	an html object
	
	
Function: JAME.DOM.firstNode

	Get the first node of a section


Arguments:
	oHTMLElement - an HTML object 

Example:
	>JAME.DOM.lastNode(JAME.$("contents"));
	
	><div id="contents">
	><h2>My contents</h2>
	><p>My paragraph 1</p>
	></div>
    >//will return the html object,h2, containing My contents

Returns:
	an html object
	
Function: JAME.DOM.prevNode

	Get the previous node of a section


Arguments:
	oHTMLElement - an HTML object 

Example:
	>JAME.DOM.prevNode(JAME.$("p"));
	
	><div id="contents">
	><h2>My contents</h2>
	><p>My paragraph 1</p>
	></div>
    >//will return the html object,h2, containing My contents
	
Returns:
	an html object
	
Function: JAME.DOM.nextNode

	Get the next node of a section


Arguments:
	oHTMLElement - an HTML object 

Example:
	>JAME.DOM.prevNode(JAME.$("h2"));
	
	><div id="contents">
	><h2>My contents</h2>
	><p>My paragraph 1</p>
	></div>
    >//will return the html object,p, containing My contents

Returns:
	an html object
	
Function: JAME.DOM.getText

	Get the text without the html tags


Arguments:
	oHTMLElement - an HTML object 

Example:
	>JAME.DOM.getText(JAME.$("contents"));
	
	><div id="contents">
	><h2>My contents</h2>
	><p>My paragraph 1</p>
	></div>
    >//will return "My contents My paragraph 1"

Returns:
	a string
	
Function: JAME.DOM.Ready

	Execute the function as soon as the DOM is ready


Arguments:
	function 

Example:
	>JAME.DOM.Ready(function() {
	
	   JAME.$("contents").innerHTML="DOM is ready";
	
	});

Returns:
	a string

	
Section: DOM manipulation related functions

Function: JAME.DOM.createNode

	Will create the html tag element

Arguments:
	string - the name of an html tag 

Example:
	>var paragraph = JAME.DOM.createNode("p");

Returns:
	a string
	
Function: JAME.DOM.wrapNode

	wrap a node within an other one


Arguments:
	oHTMLElement - the element to wrap
	string       - the name of the tag wrapping

Example:
	>var div = JAME.DOM.wrapNode(JAME.$("contents"),"div");

	><div id="contents">
	><h2>My contents</h2>
	><p>My paragraph 1</p>
	></div>
    >//will be changed into:

	><div>
	><div id="contents">
	><h2>My contents</h2>
	><p>My paragraph 1</p>
	></div>
	></div>

Returns:
	the newly created wrapping html element
	
Function: JAME.DOM.insertNodeAfter

	insert a node after an other one


Arguments:
	oHTMLElement - the element to insert
	oHTMLElement - after this element

Example:
	>var title = JAME.DOM.insertNodeAfter(JAME.$("mytitle"),JAME.$("contents"));

	><div id="contents">
	><h2 id="mytitle">My contents</h2>
	><p>My paragraph 1</p>
	></div>
	
    >//will be changed into:

	><div id="contents">
	><p>My paragraph 1</p>
	></div>
	><h2>My contents</h2>
	
Returns:
	void

	
Function: JAME.DOM.insertNodeBefore

	insert a node before an other one


Arguments:
	oHTMLElement - the element to insert
	oHTMLElement - before this element

Example:
	>var title = JAME.DOM.insertNodeBefore(JAME.$("mytitle"),JAME.$("contents"));

	><div id="contents">
	><h2 id="mytitle">My contents</h2>
	><p>My paragraph 1</p>
	></div>
	
    >//will be changed into:

	><h2>My contents</h2>
	><div id="contents">
	><p>My paragraph 1</p>
	></div>
	
Returns:
	void

Function: JAME.DOM.contains

	verify that a string is contained within an other

Arguments:
	sString    - the string to search in
	sSearch    - the searched string
	sSeparator - the separator within the sString,ie space, hyphen...

Example:
	>var isSelected = JAME.DOM.contains(JAME.$("mytitle").className,'selected',' ');
	
Returns:
	true if the string is found, false if not

Function: JAME.DOM.hasClass

	verify that an HTML element className contains the searched string

Arguments:
	oHTMLElement - the html element
	sSearch      - the searched class name 

Example:
	>var hasClass = JAME.DOM.hasClass(JAME.$("mytitle"),'selected');
	
Returns:
	true if the string is found, false if not


Function: JAME.DOM.hasAttr

	verify that an (HTML) object contains an attribute with a certain value

Arguments:
	sAttrName - the attribute/property name
	sValue    - the attribute value
	oScope	  - the object to search in

Example:
	>var hasAttr = JAME.DOM.hasAttr('className','',JAME.$('title'));
	
Returns:
	true if the string is found, undefined if not

Function: JAME.DOM.byTag

	find the HTML element by tag name

Arguments:
	sTagName     - the searched tag name
	oHTMLElement - the html element to search within (default to document)

Example:
	>var paragraphs = JAME.DOM.byTag('p',JAME.$('container'));

Returns:
	array of found elements >=0

Function: JAME.DOM.byTags

	find the html elements contain in different HTML elements

Arguments:
	sTagName     - the searched tag name
	oHTMLElements - an html element or an array of html elements to search within (default to document)

Example:
	>var paragraphs = JAME.DOM.byTags('p',[JAME.$('container1'),JAME.$('container2')]);

Returns:
	an array with 0 to x elements

Function: JAME.DOM.byAttr

	verify that the (HTML) objects contain an attribute with a certain value

Arguments:
	sAttrName - the attribute/property name
	sValue    - the attribute value
	oScope	  - the object or an array of object to search in

Example:
	>var attrs = JAME.DOM.byAttr('className','',[JAME.$('title'),JAME.$('title2')]);
	
Returns:
	array of found elements >=0

Function: JAME.DOM.byClass

	find elements containing the specified class name

Arguments:
	sclassName - the class name
	oScope	   - an array of object to search in

Example:
	>var selected = JAME.DOM.byClass('selected',[JAME.$('title'),JAME.$('title2')]);
	
Returns:
	array of found elements >=0

Function: JAME.DOM.addClass

	add the class name to an html element

Arguments:
	oHTMLElement - an html object
	sclassName   - the class name

Example:
	>JAME.DOM.addClass(JAME.$('title'),'title1');
	>JAME.DOM.addClass(JAME.$('title'),'selected');
	>alert(JAME.$('title').className); // output 'title1 selected' - if no previous class names have been set
	
Returns:
	void


Function: JAME.DOM.removeClass

	remove the class name of an html element

Arguments:
	oHTMLElement - an html object
	sclassName   - the class name

Example:
	>JAME.DOM.addClass(JAME.$('title'),'title1');
	>JAME.DOM.addClass(JAME.$('title'),'selected');
	>JAME.DOM.removeClass(JAME.$('title'),'selected');
	>alert(JAME.$('title').className); // output 'title1' - if no previous class names have been set
	
Returns:
	void

Function: JAME.DOM.toggleClass

	toggle the class name of an html element

Arguments:
	sclassName   - the class name
	oHTMLElement - an html object

Example:
	>JAME.DOM.addClass('title1',JAME.$('title'));
	>JAME.DOM.toggleClass('selected',JAME.$('title'));
	>alert(JAME.$('title').className); // output 'title1 selected' - if no previous class names have been set
	>JAME.DOM.toggleClass('selected',JAME.$('title'));
	>alert(JAME.$('title').className); // output 'title1' - if no previous class names have been set	

Returns:
	void

Function: JAME.DOM.addKey

   add a key linked to an object

Arguments:
	oHTMLElement - the object to attach the data to
	sKey	     - the name of the key to which the data will be attached to
	Val		     - the value being any possible javascript variable possible

Example:
	>JAME.DOM.addKey(JAME.$('title'),'isAnimating',true);
	>var isAnimating = JAME.DOM.getKey(JAME.$('title'),'isAnimating');
	>alert(isAnimating); //true
	>JAME.DOM.removeKey(JAME.$('title'),'isAnimating');
	>isAnimating = JAME.DOM.getKey(JAME.$('title'),'isAnimating');
	>alert(isAnimating); //undefined

Returns:
	void

Function: JAME.DOM.getKey

   get a key linked to an object

Arguments:
	oHTMLElement - the object to attach the data to
	sKey	     - the name of the key to which the data will be attached to

Example:
	>JAME.DOM.addKey(JAME.$('title'),'isAnimating',true);
	>var isAnimating = JAME.DOM.getKey(JAME.$('title'),'isAnimating');
	>alert(isAnimating); //true
	>JAME.DOM.removeKey(JAME.$('title'),'isAnimating');
	>isAnimating = JAME.DOM.getKey(JAME.$('title'),'isAnimating');
	>alert(isAnimating); //undefined

Returns:
	void

Function: JAME.DOM.addKey

   add a key linked to an object

Arguments:
	oHTMLElement - the object to attach the data to
	sKey	     - the name of the key to which the data will be attached to
	Val		     - the value being any possible javascript variable possible

Example:
	>JAME.DOM.addKey(JAME.$('title'),'isAnimating',true);
	>var isAnimating = JAME.DOM.getKey(JAME.$('title'),'isAnimating');
	>alert(isAnimating); //true
	>JAME.DOM.removeKey(JAME.$('title'),'isAnimating');
	>isAnimating = JAME.DOM.getKey(JAME.$('title'),'isAnimating');
	>alert(isAnimating); //undefined

Returns:
	void

Function: JAME.DOM.removeKey

   remove a key linked to an object

Arguments:
	oHTMLElement - the object to attach the data to
	sKey	     - the name of the key the data will be removed from

Example:
	>JAME.DOM.addKey(JAME.$('title'),'isAnimating',true);
	>var isAnimating = JAME.DOM.getKey(JAME.$('title'),'isAnimating');
	>alert(isAnimating); //true
	>JAME.DOM.removeKey(JAME.$('title'),'isAnimating');
	>isAnimating = JAME.DOM.getKey(JAME.$('title'),'isAnimating');
	>alert(isAnimating); //undefined

Returns:
	void

Function: JAME.DOM.removeAllKeys

   remove all keys linked to an object

Arguments:
	oHTMLElement - the object to attach the data to

Example:
	>JAME.DOM.addKey(JAME.$('title'),'isAnimating',true);
	>JAME.DOM.addKey(JAME.$('title'),'toggleNamed','my js title');
	>JAME.DOM.removeAllsKeys(JAME.$('title'));
	>var isAnimating = JAME.DOM.getKey(JAME.$('title'),'isAnimating');
	>alert(isAnimating); //undefined
	>var toggleNamed = JAME.DOM.getKey(JAME.$('title'),'toggleNamed');
	>alert(toggleNamed); //undefined

Returns:
	void

 

 * html
 * append
 * val
 * remove
 * empty
 * clone
 */

JAME.DOM = {
   lastNode : function (elm) {
      if (!elm.lastChild) return false;
      elm = elm.lastChild;
      return (elm && elm.nodeType!=1)
          ? JAME.DOM.prevNode(elm) 
          : elm;
   },
   prevNode : function(elm) {
      if (!elm)  return false; 
      do {
        elm = elm.previousSibling;
      } while (elm && elm.nodeType!=1);
      return elm;
   },
   nextNode : function(elm) {
       if (!elm) return false;
       do { elm = elm.nextSibling; } while (elm && elm.nodeType!=1);
       return elm;
   },
   firstNode : function(elm) {
      if (!elm.firstChild) return false;
      elm = elm.firstChild;
      return (elm && elm.nodeType!=1)
             ? JAME.DOM.nextNode(elm) 
             : elm;
   },
   getText : function(elm) {
      var txt=[];
      elm = elm.childNodes;
      for(var i=0,ln=elm.length;i<ln;i++) {
         txt.push(
              (elm[i].nodeType!=1) 
              ? elm[i].nodeValue 
              : JAME.DOM.getText(elm[i])
        )
      }
      return txt.join('');
   },
   Ready : function (f) {
      if (JAME.DOM.Ready.loaded) return f();


	  //the load event can fire before the dom is ready (page is cashed)
	  JAME.Events.addListener(window,'load',function() { setTimeout(JAME.DOM.__isDOMReady,0)});

      if (!JAME.DOM.Ready.pool) {
          JAME.DOM.Ready.todo = [ f ];
          JAME.DOM.Ready.pool = setInterval(JAME.DOM.__isDOMReady,10);
      }
      else
        JAME.DOM.Ready.todo.push(f);
   },
   __isDOMReady : function () {
      if (JAME.DOM.Ready.loaded) return false;

		/* see http://javascript.nwbox.com/IEContentLoaded/ */
		try {
			var d = document;
			if(window.attachEvent){
				d.documentElement.doScroll('left');
			}
		}catch(e){
			return;
		}

      if (document && document.body && document.getElementById) {

         clearInterval(JAME.DOM.Ready.pool);

         for (var i = 0,ln=JAME.DOM.Ready.todo.length; i < ln; i++){
            JAME.DOM.Ready.todo[i]();
		 }
         JAME.DOM.Ready.todo = null;
         JAME.DOM.Ready.loaded = true;
      }
    },
    createNode : function(node) {
        return document.createElement(node);
    },
    wrapNode : function(elm,wrapper) {
        var oWrapper = JAME.DOM.createNode(wrapper);
        var elmClone = elm.cloneNode(true);
        oWrapper.appendChild(elmClone);
        oparent = elm.parentNode;
        JAME.DOM.insertNodeAfter(oWrapper,elm);
        oparent.removeChild(elm);
        return oWrapper;
    },
    insertNodeBefore : function(elm, targetElm ) {
         var oparent = targetElm.parentNode;
         oparent.insertBefore(elm, targetElm);
    },
    insertNodeAfter : function(elm, targetElm ) {
       var oparent = targetElm.parentNode;
       if (targetElm == oparent.lastChild)
           oparent.appendChild(elm);
        else
           oparent.insertBefore(elm,JAME.DOM.nextNode(targetElm));
    },
	contains : function(str,item,sep) {
		return ((sep+str+sep).indexOf(sep+item+sep)>-1);
	},
	hasClass : function(elm,sClass){
		return JAME.DOM.contains(elm.className,sClass,' ');
	},
    hasAttr:function(attr,val,scope) {
        if(scope[attr]==val) return scope;
        if(parseInt(scope[attr])===val) return scope;
        if(parseInt(scope[attr])===parseInt(val)) return scope;
		return undefined;
    },
    byTags:function(tag,scope) {

        if(scope===undefined) return JAME.DOM.byTag(tag);
        scope = (scope.constructor!==Array) ? [scope] : scope;

        var elms = [];
        for(var i = 0; i < scope.length; i++) { 
            var s = scope[i];
            var r = JAME.DOM.byTag(tag,s);
            if(r.length>0) {
               for(var j = 0; j < r.length; j++) {
					elms.push(r[j]);
			   }
            }
        }
        return elms;
    },
    byAttr:function(attr,val,scope) {
        scope = (scope.constructor!==Array) ? [scope] : scope;
        var elms=[];
        for(var i=0;i<scope.length;i++) { 
            var s=scope[i];
            var r= JAME.DOM.hasAttr(attr,val,s);
            if(r) elms.push(r);
        }
        return elms;
    },
	byClass: function(t,s) {
        var ar = [];
        s      = s || document.body.getElementsByTagName('*');
        var e;
        for(var i=0,ln=s.length;i<ln;i++) {
            e=s[i];
            if (e.className) {
				var reg = new RegExp('\s*'+t+'\s*');
				if (reg.test(e.className)) 
					ar.push(e);
			}
        }
        return ar;
    },
    byTag: function(tag,scope) {
        if(tag=="body") return document.body;
        var elms = (scope || document).getElementsByTagName(tag);
        var ar = [];
        for(var i=0,ln=elms.length;i<ln;i++) ar.push(elms[i]);
        return ar;
    },
	addClass : function(elm,sClass){
		elm.className = (elm.className) ? elm.className+' '+ sClass : sClass;
	},
	removeClass : function(elm,sClass){
		var str = elm.className;
		elm.className = str.replace(new RegExp('\s*'+sClass+'\s*'),'');
	},
	toggleClass :  function(elm,sClass){
		JAME.DOM[JAME.DOM.hasClass(elm,sClass) ? 'removeClass': 'addClass'](elm,sClass);
	},
	addKey : function(elm,key,value) {
		JAME.__STORE__.add(elm,key,value);
	},
	getKey : function(elm,key) {
		JAME.__STORE__.get(elm,key);
	},
	removeKey : function(elm,key) {
		JAME.__STORE__.remove(elm,key);
	},
	removeAllKeys : function(elm) {
		JAME.__STORE__.removeAll(elm);
	},
    Export : function() {
        JAME.Exporter(JAME.DOM);
    }
};

/*!require: JAME, JAME.DOM */

JAME.Package("JAME.CSS.Selector");

/*

Title: JAME Javscript Animation Made Easy

package: JAME.CSS.Selector

	The Selector package holds the css selector parser.

	With this package you can use modern css3 selectors on your content

	and get a quick and easy access to what you need in a matter of a line.

	Don't need to say that it is way much shorter than a pure DOM traversial

 	as the package does all the dirty in the background!

	
	Anyhow!:

	Speech-less, code more.

    Here is a little example to get you started.

	Short indeed!


Example:

	(start code)
   
	var lis  = JAME.CSS.Selector.parse('div.container .items > li');

	(end)

*/


JAME.CSS.Selector = {
    normalizeSelector : function(str) {
		return str.replace(/\s+/g,' ');
	},
	
	parse : function(str) {
		
		str = JAME.CSS.Selector.normalizeSelector(str);

        if(str=="*")   return JAME.DOM.byTag("*"); 
		  
		var selector = undefined;
        var elm      = undefined;
		  
        var r        = str.split('');

		var funcs = JAME.CSS.Selectors;

		MAIN:
        for(var i=0,ln=r.length;i<ln;i++) {

              if(!/[a-zA-Z0-9_-]/.test(r[i])) { 
                   selector=r[i];
              }
              else {

                   var regex  = '^.{'+i+'}([a-zA-Z0-9_-]+)';
                   var reg    = new RegExp(regex);
                   var result = reg.exec(str);
                   var tag    = result[1];

				   for(var func in funcs) {
				   	   var ret = funcs[func](tag, i, r, selector, elm);
					   if(ret==-1) return [];
				   	   if (tag.length === r.length && ret) return ret.constructor===Array ? ret : [ret];
				   	   if (ret) {
				   		  elm = ret;
				   		  i   = tag.length - 1 + i;
				   		  continue MAIN;
				   	   }
				   }
                   i  = tag.length-1+i;
               }
         }
         return ret.constructor===Array ? ret : [ret];	
	},
	sendResult : function(elm) {
		    return elm ? elm : -1;
	}
}
JAME.CSS.Selectors = {
	
   _byId: function(searchTag,inLoop,aSelection,lastSelector,elms) {
        if (lastSelector == '#')
	 	    return JAME.CSS.Selector.sendResult(JAME.$(searchTag));
        return false;
   },
   _byTag: function(searchTag,inLoop,aSelection,lastSelector,elms) {

       if ((lastSelector == ' ' || !lastSelector))
	   		return JAME.CSS.Selector.sendResult(JAME.DOM.byTags(searchTag, elms));
       return false;
   },
   _byClass: function(searchTag,inLoop,aSelection,lastSelector,elms) {

       if(lastSelector == '.') {
          if (/\s/.test(aSelection[inLoop - 2])) {
			elms = JAME.DOM.byTags('*', elms);
		  }
		  return JAME.CSS.Selector.sendResult(JAME.DOM.byClass(searchTag, elms));
       }
       return false;
  }, 
  _getDirectChildOf: function(searchTag,inLoop,aSelection,lastSelector,elms) {
    if(lastSelector=='>'){
        tags = JAME.DOM.byTags(searchTag,elms);

        if(!tags) return; 
        var ret=[];
        for(var i=0,ln=tags.length;i<ln;i++) { 
            var s=tags[i];
            var parent=s.parentNode;
            if(parent) for(var j=0,ln2=elms.length;j<ln2;j++) if(parent===elms[j]) ret.push(s);
        }

        return ret;
    }
    return false;
  },
  _getDirectSiblingOf: function(searchTag,inLoop,aSelection,lastSelector,elms) {
    if(lastSelector=='+'){
            searchTag=searchTag.toLowerCase();
        var ret=[];
        for(var i=0,ln=elms.length;i<ln;i++) { 
            var s=elms[i];
                s=JAME.DOM.nextNode(s);
            if(n && n.nodeName.toLowerCase()==searchTag) ret.push(n);
        }
        return ret;
    }
    return false;
  },
  _getFirstSiblingOf: function(searchTag,inLoop,aSelection,lastSelector,elms) {
    if(lastSelector=='~'){
            searchTag=searchTag.toLowerCase();
 
        var ret=[];
        elms = (elms.constructor===Array) ? elms : [elms];
        for(var i=0,ln=elms.length;i<ln;i++) { 
            var n=elms[i];

            do {
               n=JAME.DOM.nextNode(n);
            } while(n && n.nodeName.toLowerCase()!=searchTag);
            if(n) ret.push(n);
        }
        return ret;
    }
    return false;
  }
};


/*!require: JAME */
JAME.Package('JAME.Util.String');

/*
Title: JAME.Util.String - Helper functions

Package: JAME.Util.String

    Define string functions used in the FX related package.

base: JAME

    <JAME>

About:
    Version 0.01



Function: JAME.Util.String.camelize
        Change a string using hypen separators into camel case.	

Arguments:
    string - the string to camelize.

Example:
    >JAME.Util.String.camelize('background-color'); // return backgroundColor

Returns:
    the camelized string.

See Also:

      <JAME.Util.String.hyphenize> , <JAME.Util.String.firstToUpperCase>

Function: JAME.Util.String.hyphenize
        Change a string using camel case style into a hyphen separated string.	

Arguments:
    string - the string to hyphenize.

Example:
    >JAME.Util.String.hyphenize('backgroundColor'); // return 'background-color'

Returns:
    the hyphenized string.

See Also:

      <JAME.Util.String.camelize> , <JAME.Util.String.firstToUpperCase>

Function: JAME.Util.String.firstToUpperCase
        Change the first letter of a string into uppercase.	

Arguments:
    string - the string to modify.

Example:
    >JAME.Util.String.firstToUpperCase('backgroundColor'); // return 'BackgroundColor'

Returns:
    the string with the first letter in upper case

See Also:

      <JAME.Util.String.camelize> , <JAME.Util.String.hyphenize>

Function: JAME.Util.String.trim

    Eliminate spaces at the beginning and the end of the string	

Arguments:
    string - the string to modify.

Example:
    >JAME.Util.String.trim('   backgroundColor   '); // return 'backgroundColor'

Returns:
    the string without trailing spaces

Section: Exported functions
    JAME.Import(JAME.Util.String);

Function: camelize
    <JAME.Util.String.camelize>

Function: hyphenize
    <JAME.Util.String.hyphenize>

Function: firstToUpperCase
    <JAME.Util.String.firstToUpperCase>

Function: trim
    <JAME.Util.String.trim>


*/

JAME.Util._String={
    _camelize: function(str) {
        return str.replace(/-(.)/g, function(m, l){return l.toUpperCase()});
    },
    _hyphenize : function(str) {
        return str.replace(/([A-Z])/g, function(m, l){return '-'+l.toLowerCase()});
    },
    _firstToUpperCase : function(str) {
         return str.replace(/^([a-z])/, function(m, l){return l.toUpperCase()});
    },
    _trim : function(str) {
         return str.replace(/^\s+|\s+$/g, '');
    }
};



JAME.Util.String={};

for(var prop in JAME.Util._String) {
	(function(prop){
		var func = prop.replace(/^_/,"");
		JAME.Util.String[func] = function(str) {
			return JAME.Util._String[prop](str);
		}
	})(prop);
}

JAME.Util.String.Export = function() {
	JAME.Exporter(JAME.Util.String);
}


/*!require: JAME, JAME.Util.String */
JAME.Package('JAME.CSS');


/*
Title: JAME Javscript Animation Made Easy

package: JAME.CSS

base: JAME JAME/Util/String

<JAME>
<JAME.Util.String>

Function: JAME.CSS.setOpacity
	
	set the opacity of an html Element

Arguments:
	oHTMLElement - the element to which you want to apply the opacity
	int          - the value of opacity from 0 to 1

Example:
	>JAME.CSS.setOpacity(JAME.$("mydiv"),.75);


Returns:
	void
	

Function: JAME.CSS.setStyle
	
	set one css property on an element

Arguments:
	oHTMLElement - the element to which you want to apply the css style
	sProperty    - the css property name (height, width,size...)
	sValue       - the corresponding value. px is the default 

Example:
	>JAME.CSS.setStyle(JAME.$("mydiv"),"size",12);
	>JAME.CSS.setStyle(JAME.$("mydiv"),"border","1px solid #FF00FF");

Returns:
	void
	
Function: JAME.CSS.setStyles
	
	set several css properties on an element
Arguments:
	oHTMLElement - the element to which you want to apply the css style
	Hash    - the css property name (height, width,size...) as a key with its the corresponding value. px is the default 

Example:
	(start code)
	JAME.CSS.setStyles(JAME.$("mydiv"),{
	    size:12,
	    border:"1px solid #FF00FF",
	    'font-weight':700 //or fontWeight : 700
	});
	(end)

Returns:
	void
	
	
Function: JAME.CSS.getStyle
	
	get a css property's value of an element
	
Arguments:
	oHTMLElement - the element you want to get the value from
	sProperty    - the css property name (height, width,size...). 

Example:
	>var height = JAME.CSS.getStyle(JAME.$("mydiv"),"height");



Returns:
	The computed style of the element

	
*/

JAME.extend(JAME.CSS,{
   setOpacity : function (obj,amount) {
     
            obj.style.zoom = 1;
            obj.style.filter = "alpha(opacity=" + amount*100 + ")";
			obj.style.opacity = amount;

   },
   _float : function() {
      var prop = (window.attachEvent) ? 'styleFloat' : 'cssFloat';
      JAME.CSS._float=function() { return prop; };
      return prop;
   },
   setStyle : function (elm,prop,val) {

      elm = (elm.constructor===Array) ? elm : [elm];
      for(var i=0;i<elm.length;i++) {
        if(prop=='opacity') { 
           JAME.CSS.setOpacity(elm[i],parseFloat(val));
           continue;
         }
    //     if(prop=='float')   prop = JAME.CSS._float();
         prop = JAME.Util.String.camelize(prop);
         unit=(prop=='zIndex'||prop=='zoom'||prop.lastIndexOf('olor')!=-1) ? '':'px';

         elm[i].style[prop] = (typeof val=='string') ? val : val+unit; 

      }
   },

   setStyles : function (elm,props) {
      for(var prop in props) {
        JAME.CSS.setStyle(elm,prop,props[prop]);
      }
   },

	_hasGetStyleProperParams :function(elm, style) {
		return true;
	},

	_compliantGetStyle : function(elm, style,option){

		style = JAME.Util.String.camelize(style);

        if(elm.style && elm.style[style]) {
			return elm.style[style];
		}

		style = JAME.Util.String.hyphenize(style);

		//safari 4.0.3 will send back the difference between the element 
		//and the window port so margin-right:5px might send back 923px
		//by setting the position to absolute, safari sends back the proper value
		var oldPosition = undefined;
        var computed    = document.defaultView.getComputedStyle(elm, "");
		if(style==="margin-right"){
			oldPosition =computed.getPropertyValue("position");
			//avoid FF3.5: cannot access optimized closure by not calling the function setStyle
			elm.style.position="absolute";
		}

		var val = computed.getPropertyValue(style);
		if(oldPosition)
			elm.style.position=oldPosition;
        if (style == 'height' || style == 'width') {
           val = JAME.CSS._getXorY(elm, style,option);
        }

        return val;
   },
	_ieGetStyle : function(elm, style,option){

	   	if(!JAME.CSS._hasGetStyleProperParams(elm,style)) return;

		style = JAME.Util.String.camelize(style);

         if(style=='float')   style = 'styleFloat';	
         if(elm.style && elm.style[style]) return elm.style[style];
         var val= elm.currentStyle[style];
         if (style == 'height' || style == 'width') {
               val = JAME.CSS._getXorY(elm, style,option);
         }
         return val;
   },

   getStyle : function (elm,style,option) {
        if (document.defaultView && document.defaultView.getComputedStyle) {
            JAME.CSS.getStyle = JAME.CSS._compliantGetStyle;
        }
        else if (elm.currentStyle) {
            JAME.CSS.getStyle = JAME.CSS._ieGetStyle;
		}
        return JAME.CSS.getStyle(elm,style,option);
    },
	_forceLayout:{
		display:'',
		visibility:'hidden',
		position:'absolute',
		zooom:1
	},
    _getXorY : function(elm,XY,option) {

        var mXY = XY=='height' ? 'Height' : 'Width';
        var TL  = XY=='height' ? ['Top','Bottom'] : ['Left','Right'];
		var val = 0;

		if(option) {
			option      = option.replace(/ +/," ");
			var options = option.split(/ /);
			options = options.constructor===Array ? options :[option];

			JAME.each(options,function(op) {
				var pair = op.match(/-/) ? '-' : '+';
				if(op.match(/border|padding/) && pair=='+') return;
				if(op.match(/margin/) && pair=='-') return;
				op = op.replace(/-|\+/,"");
				var suf = op==="border" ? 'Width':'';
				JAME.each(TL,function(pos){
					if(pair==='+')
						val+= parseInt(JAME.CSS.getStyle(elm,op+pos+suf));
					if(pair==='-')
						val-= parseInt(JAME.CSS.getStyle(elm,op+pos+suf));
				});
			});

		}

		var display =JAME.CSS.getStyle(elm,'display');
        if(display!='none') {
            return val + elm["offset"+mXY];
		}
        var oldStyle = {
            display    : display,
            visibility : JAME.CSS.getStyle(elm,'visibility'),
            position   : JAME.CSS.getStyle(elm,'position')
        };
        JAME.CSS.setStyles(elm,JAME.CSS._forceLayout);
        var offset = elm["offset"+mXY];
        JAME.CSS.setStyles(elm,oldStyle);
        return val+offset;
    },
    Export : function() {
        JAME.Exporter(this);
    }
});

/*!require: JAME */
JAME.Package('JAME.Util.Number');

/*
Title: JAME.Util.Number

Script: Number.js
    JAME.Util.Number - numeric related functions

    Define numeric functions used in the FX related package.

Dependency:
    JAME.js

About:
    Version 0.01

Function: JAME.Util.Number.d2h
        Change a decimal integer into its hexadecimal representation	

Arguments:
    int - the decimal value 

Example:
    >JAME.Util.Number.d2h(255); // return FF

Returns:
    the hexadecimal value.

See Also:

      <JAME.Util.Number.h2d>

Function: JAME.Util.Number.h2d
        Change an hexadecimal value into its decimal representation	

Arguments:
    int - the hexadecimal value.

Example:
    >JAME.Util.Number.h2d(FF); // return 255

Returns:
    the decimal value

See Also:

      <JAME.Util.Number.d2h>

Section: Exported functions
    JAME.Import(JAME.Util.Number);

Function: d2h
    <JAME.Util.Number.d2h>

Function: h2d
    <JAME.Util.Number.h2d>

*/

JAME.Util.Number= {
    d2h : function(dec) { 

       return dec.toString(16);
    },
    h2d :function(hex) { 

       return parseInt(hex,16);
   },
   Export : function() {
    JAME.Exporter(this);
   }
};
/*!require: JAME,JAME.Util.Number */

JAME.Package('JAME.Util.Color');
/*
Title: JAME.Util.Color

Script: Color.js
    JAME.Util.Color - color related functions

    Convert from one color scheme to an other (rgb<=>hex). Used within the FX package

Dependency:

    <JAME.js>
	<JAME.Util.Number>

About:
    Version 0.01

Function: JAME.Util.Color.rgb2h
        Change a set of 3 decimal integer into its hexadecimal representation	

Arguments:
    iIntegers - an array containing the 3 value of the rgb set 

Example:
    >JAME.Util.Color.rgb2h(255,0,122); // return ["ff",0,"7a"];

Returns:
    an array with the 3 hexadecimal representation of the integers.

See Also:

      <JAME.Util.Color.h2rgb>

Function: JAME.Util.Color.h2rgb
        Change a set of 3 hexadecimal values into their decimal representation	

Arguments:
    iValues - the 3 hexadecimal values

Example:
    >JAME.Util.Color.h2rgb("ff",0,"7a"); // return [255,0,122]

Returns:
    an array with the 3 integer representation of the hexadecimal values.

See Also:

      <JAME.Util.Color.rgb2h>

Function: JAME.Util.Color.cssColor2rgb
        Cross-browser function to change a set of colors defined via css into an array of 3 decimal values	

Arguments:
    sCSSColor - the string color defined via css 

Example:
    >JAME.Util.Color.cssColor2rgb("#ff007a"); 		  // return [255,0,122]
    >JAME.Util.Color.cssColor2rgb("#fff"); 		  	  // return [255,255,255]
    >JAME.Util.Color.cssColor2rgb("rgb(255,0,122)");  // return [255,0,122]

Returns:
    an array with the 3 integer representation of the hexadecimal values.


Section: Exported functions
    JAME.Import(JAME.Util.Color);

Function: rgb2h
    <JAME.Util.Color.rgb2h>

Function: h2rgb
    <JAME.Util.Color.h2rgb>

Function: cssColor2rgb
    <JAME.Util.Color.cssColor2rgb>

*/

new function() {

      var d2h = JAME.Util.Number.d2h;
      var h2d = JAME.Util.Number.h2d;

      JAME.Util.Color = {
           rgb2h:function (r,g,b) { 
				r=d2h(r);
				if(r===undefined) return r;
				g=d2h(g);
				if(g===undefined) return g;
				b=d2h(b);
				if(b===undefined) return b;
              return [r,g,b];
           },
           h2rgb:function (h,e,x) {  
				h=h2d(h);
				if(h===undefined) return h;
				e=h2d(e);
				if(e===undefined) return e;
				x=h2d(x);
				if(x===undefined) return x;
              return [h,e,x];
           },
           _hexStr2rgbArray:function (color) {
				if(color.split("").length===4){
					 var r=color.substring(1,2),g=color.substring(2,3),b=color.substring(3,4);
					 return JAME.Util.Color.h2rgb(r+""+r,g+""+g,b+""+b)
				}
				else {
              		return JAME.Util.Color.h2rgb(color.substring(1,3),color.substring(3,5),color.substring(5,7));
				}
           },
           _rgbStr2rgbArray:function (color) {
              return color.substring(4,color.length-1).split(',');
           },
           cssColor2rgb:function (color) {
              if(/^#[0-9a-fA-F]{3,6}$/.test(color)) {
                return JAME.Util.Color._hexStr2rgbArray(color);
              }
			  else if(/^rgb\([0-9]{1,3},[0-9]{1,3},[0-9]{1,3}\)$/.test(color)) {
              	return JAME.Util.Color._rgbStr2rgbArray(color);
			  }
			  else {
              	return undefined;
			  }
           },
           Export : function() {
                JAME.Exporter(this);
           }
      };

};

/*!require: JAME */
JAME.Package("JAME.HTMLMixin");

JAME.HTMLMixin = {

      set : function(attrs) {
        attrs=attrs ||{};
        for(var attr in attrs) {
            if(attr=='class') this.elm['className']=attrs[attr];	
            this.elm[attr]=attrs[attr];
        }
        return this;
      },
      getElement : function() {
            return this.elm;
      },
      add : function() {
        for (var i = 0, ln = arguments.length; i < ln; i++) {
            this.elm.appendChild(arguments[i].getElement());
            this.elm._elements.push(arguments[i]);
        }
        return this;
      },
      toQueryString : function(params) {
        if(!params) return null;
        var query = [];
        for (var param in params) {
            var values = params[param];
            values = (typeof values=="string") ? [values] : values;

            for(var i=0,ln=values.length;i<ln;i++) {
                query.push(encodeURIComponent(param)+'='+encodeURIComponent(values[i]));
            }
         }
        return query.join('&');
      },
      val  : function() {}
};



JAME.Package("JAME.Form");

JAME.Form = function (attrs,elm) {

        if (attrs && /form/i.test(attrs.nodeName)) {
            elm = attrs;
            attrs={};
        }
        this.elm = elm || document.createElement('form');
        this.elm._elements=[];
		this.__init(attrs);

}

JAME.Form.serialize= function(form) {
		if(!form) return;
        if(form && form.nodeName==="undefined")
            return JAME.Form.toQueryString(form);

        var elements = form.elements;
        var query={};
        for(var i=0,ln=elements.length;i<ln;i++) {
            var elm=form[i];
            if(!elm.disabled) {
                if(!/file/i.test(elm.nodeName)) {
                    if(!query[elm.name]) {
                        var values = JAME.Form.val(elm);
                        if(values.length>0)
                            query[elm.name]=values;
                    }
                }
            }
        }
        return JAME.Form.toQueryString(query);
}
JAME.extend(JAME.Form,JAME.HTMLMixin);
JAME.extend(JAME.Form.prototype,JAME.HTMLMixin);

JAME.extend(JAME.Form,{
    val : function (elm) {
       if(/select/i.test(elm.nodeName)) {
           var index   = elm.selectedIndex;
           var values  = [];
           var options = elm.options;
           if(index>0) {
              for(var i = index, ln= options.length; i < ln; i++) {
                  var option = options[i];
                  if (option.selected) {
                     value = (window.attachEvent && !option.attributes.value.specified) ? option.text : option.value;
                     values.push(value);
                  }
              }
              return values;
           }
       }
       if(/text|hidden|password|file/i.test(elm.type) || /textarea/i.test(elm.nodeName)) {
            if(elm.value && elm.value!="") {
                var val = elm.value;
                val = val.replace(/\r/,"");
                return [val];
            }
       }
       if(/checkbox|radio/i.test(elm.type)) {
           var values = [];
           var form = JAME.Form.getForm(elm);
           var checkboxes = document.getElementsByName(elm.name);
           if(checkboxes.length==1 && elm.checked) return [elm.value];
           for(var i=0,ln=checkboxes.length;i<ln;i++) {
              if(JAME.Form.getForm(checkboxes[i])===form && checkboxes[i].checked)
                 values.push(checkboxes[i].value);
           }
           return values;
       }
       return [];
    },
    getForm: function(elm) {
          do {
             elm=elm.parentNode;
             if(/form/i.test(elm.nodeName)) return elm;
          } while(elm);
    }
});

JAME.extend(JAME.Form.prototype,{

    __init : function(attrs) {
		this.set(attrs);
        this.getChildren();
	},
    getChildren: function() {
        var elements = this.elm.elements;
        for(var i=0,ln=elements.length;i<ln;i++) {
            var elm=this.elm[i];
            if (/select/i.test(elm.nodeName)) {
                this.elm._elements.push(new JAME.SelectField(elm));
            }
            else this.elm._elements.push(new JAME.InputField(elm));
        }
    },
    getVals: function() {
        
        var elements = this.elm._elements;

        var query={};
        for(var i=0,ln=elements.length;i<ln;i++) {
            var elm=this.elm._elements[i];
            if(!elm.getElement().disabled) {
                if(!/file/i.test(elm.getElement().nodeName)) {
                    if(!query[elm.getElement().name]) {
                        var values = elm.val();
                        if(values.length>0)
                            query[elm.getElement().name]=values;
                    }
                }
            }
        }
        return query;
    }
});


JAME.Package("JAME.InputField");
JAME.InputField = function(type,attrs){
     JAME.extend(this, JAME.HTMLMixin);
     if(type.nodeName) {
            this.elm=type;
            return this;
     }
     if(type=="textarea") this.textarea(attrs);
     else this.input(type,attrs);
     return this;
}

JAME.extend(JAME.InputField.prototype, {
    val : function() {
        var val = this.elm.value || this.elm.innerHTML;
        if(val && val!="") {
                val = val.replace(/\r/,"");
                return [val];
        }
        return [];
    },
    input: function(type, attrs,elm){
        this.elm = elm || document.createElement('input');
        this.elm["type"] = type;
        this.set(attrs);
        return this;
    },
    textarea : function(attrs) {
        this.elm = document.createElement('textarea');
        if(attrs["value"])  {
            this.elm.innerHTML=attrs["value"];
            delete attrs["value"];
        }
        this.set(attrs);
        return this;
    }
});



JAME.Package("JAME.SelectField");
JAME.SelectField = function(attrs,value){
     JAME.extend(this, JAME.HTMLMixin);
        if(/select/i.test(attrs.nodeName)) {
            this.elm=attrs;
            return this;
        }
     this.select(attrs,value);
     return this;
}

JAME.extend(JAME.SelectField.prototype, {
    val : function() {
           var index   = this.elm.selectedIndex;
           var values  = [];
           var options = this.elm.options;
           if(index>=0) {
              for(var i = index, ln= options.length; i < ln; i++) {
                  var option = options[i];
                  if (option.selected) {
                     value = (window.attachEvent && !option.attributes.value.specified) ? option.text : option.value;
                     values.push(value);
                  }
              }
              return values;
           }
           return [];
    },
    select: function(attrs,values){
        this.elm = document.createElement('select');
        this.set(attrs);
        for(var value in values){
            var option=document.createElement('option');
            option.value=value;
            option.innerHTML=values[value];
            this.elm.appendChild(option);
        }
        return this;
    }
});

/*!require: JAME */
JAME.Package('JAME.Browser');

new function() {

// almost verbatim from jquery.com 

var ua        = navigator.userAgent,
    platform  = navigator.platform;
	ua        = ua.toLowerCase();
	var match = /(webkit)[ \/]([\w.]+)/.exec( ua )              ||
			    /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) ||
			    /(msie) ([\w.]+)/.exec( ua )                    ||
			    !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) || [];

	var browser = match[1] || "",
	    version = match[2] || "0";


JAME.Browser.Engine = {
	trident : function() {
		return (browser.test(/msie/));
	},
	webkit : function() {
		return (browser.test(/webkit/));
	},
	gecko : function() {
		return (browser.test(/mozilla/));
	},
	platform :(navigator.platform.match(/mac|win|linux|ipod|iphone/i)),
	version : version
};


}
/*!require: JAME,JAME.HTML */

JAME.Package("JAME.Ajax");
/*
Title: JAME.Ajax - AJAX can be easy too

Script: Ajax.js
	JAME.Ajax - cross-browser remote request

About:
	Version 0.01

License:
	MIT-style license.

Credits:
       - inspired by Mootools, Jquery,Protoype and the community.
*/





/*
Function: JAME.Ajax
	Allow to create remote call to the server thru the normalized
	XMLHttpRequest.

Arguments:
	Hash of options. (See Example for further information)
	 
    Available parameters(* are required):
	
        - url*       : the url to fetch
        
        - type       : the type of the return call (xml or js else pass as raw data...)
        
        - method     : POST or GET
        
        - vars       : an hash containing params/value or a form object.
        
        - timeout    : timeout value expressed in milliseconds (default:2000)
        
        - retryDelay : the time in milliseconds to wait before trying again upon timeout (default:100)
        
        - retryLimit : the number of time the request will be made in case of timeout (default:3)
        
        - async      : request asyncrhone or not (default:true)
        
        - onSuccess  : the code to excecute upon request success. you get the fetch data as the argument
        
        - onError    : the code to execute upon failure.
        
        
        ##NOT IMPLEMENTED YET
        
        - every      : the time between each periodical call in milliseconds (allows periodical request)
        
        - everyDecay : if a request return a non-modified contents, the next periodical request
        
        will be executed later by multiplying the time set to every by this ratio (default:1.5)
	
Returns:
	void.
	
Example:

	Even if the number of parameters seems numerous, 
	you can make a request with only 2 parameters:
	
	a) simple call


                          
	(start code)
	
	
	new JAME.Ajax({
	     url:'/cgi-bin/index.cgi?ajax=true',
	     onSuccess : function(resp) {
	         JAME.$("content").innerHTML=resp;
	     }
	});
	
	
	(end)
	it will automaticly set the request as being asyncrhone
	with a method of GET.
	if your resp is sent has plain/html or plain/text, you will
	get this data not formated as a parameter of the onSuccess function.
	
	b) sending data from a form
	(start code)	
		new JAME.Ajax({
	     vars : JAME.$("my_form_name"),
	     onSuccess : function(resp) {
	         JAME.$("content").innerHTML=resp;
	     }
	});
	(end)	
	Here again, it will execute an asyncrhone request with a method of POST.
	JAME.Ajax will recognize the object passed to vars as being a form
	and will serialize the data for you and use the url set in the action attribute
	of the form tag.
	
	Most of the time, it won't get any harder than that!
	
	If you think the function is not guessing your attempt
	just set the params you need as they will take precedence.


See also:
	<JAME.Form>
*/

JAME.Ajax = function(options){
    
    this.options ={
        url        : options.url        || "",
        type       : options.type       || "",
        method     : options.method     || "",
        vars       : options.vars       || null,
        timeout    : options.timeout    || 5000,
        retryDelay : options.retryDelay || 500,
        retryLimit : options.retryLimit || 3,
        every      : options.every      || 0,
        everyDecay : options.everyDecay || 0,
        async      : options.async      || true,
        onSuccess  : options.onSuccess  || function() {},
        onError    : options.onError    || function() {}
    };
    this.retryCount=0;
    this.guessMethod();
    this.guessURL();
    this._init();
}

JAME.extend(JAME.Ajax.prototype,{
    _init: function() {

       var that = this;
       //set timeout and then the retry
       this.timer = setTimeout(function() {
           that.abortXHR();
           if (that.retryCount < that.options.retryLimit) {
                that.retryCount++;
                setTimeout(function(){
                    that._init();
                }, that.options.retryDelay);
           }
       },this.options.timeout);
    
       this.xhr = this.getXHR();

       var data = "";
       var url  = "";
       if(this.options.vars) {
          if(this.options.method=="POST")
            data = JAME.Form.serialize(this.options.vars);
          else
            url = this.appendQueryString(JAME.Form.serialize(this.options.vars));
       }

       this.xhr.open(this.options.method,this.options.url+url,this.options.async);
       if(this.options.method=="POST") {
            this.xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
            if(this.xhr.overrideMimeType)
               this.xhr.setRequestHeader("Connection","close");
       }
       this.handleResponse();
       this.xhr.send(data);
    },
/*
Function: JAME.Ajax.guessURL
	Call by <JAME.Ajax> for internal use

Arguments:
	none.

Returns:
	void.

See also:
	<JAME.Ajax>
*/
    guessURL : function() {
        if(this.options.url) return;
        var vars = this.options.vars;
        if (vars.nodeName!=="undefined") {
            this.options.url = vars.action;
            return;
        }
    },
/*
Function: JAME.Ajax.guessMethod
	Call by <JAME.Ajax> for internal use

Arguments:
	none.

Returns:
	void.

See also:
	<JAME.Ajax>
*/
    guessMethod : function() {
        if(this.options.method) return;
        var url = this.options.url;
        if (/\?/.test(url)) {
            this.options.method = "GET";
            return;
        }
        if (this.options.vars) {
            this.options.method = "POST";
            return;
        }
        this.options.method = "GET";
    },
/*
Function: JAME.Ajax.appendQueryString
	Call by <JAME.Ajax> for internal use

Arguments:
	none.

Returns:
	void.

See also:
	<JAME.Ajax>
*/
    appendQueryString : function(query) {
            var url = this.options.url;
            if(/\?.+/.test(url))
                query='&'+query;
            else if(/\?$/.test(url)) {
            }
            else 
                if(this.options.vars) query='?'+query;
            return query || "";
    },
/*
Function: JAME.Ajax.getXHR
	Call by <JAME.Ajax> for internal use

Arguments:
	none.

Returns:
	void.

See also:
	<JAME.Ajax>
*/
    getXHR: function(){
       if(window.XMLHttpRequest) {
          JAME.Ajax.prototype.getXHR = function(){
               return new XMLHttpRequest();
          }
       }
       else if(window.ActiveXObject) { 
         var xhr;
         var msxml = [
            'Msxml2.XMLHTTP.5.0',
            'Msxml2.XMLHTTP.4.0',
            'Msxml2.XMLHTTP.3.0',
            'Msxml2.XMLHTTP',
            'Microsoft.XMLHTTP'
         ];

          for (var i = 0, ln = msxml.length; i < ln; i++) {
            try {
                xhr = function(){return new ActiveXObject(msxml[i]); };
                xhr();
            } 
            catch (e){ continue; }
            break;
          }
          JAME.Ajax.prototype.getXHR = xhr;
       }
       else {  
           throw new Error("XMLHTTPRequest not supported..."); 
       } 
       return JAME.Ajax.prototype.getXHR();
    },
/*
Function: JAME.Ajax.handleResponse
	Call by <JAME.Ajax> for internal use

Arguments:
	none.

Returns:
	void.

See also:
	<JAME.Ajax>
*/
    handleResponse: function(){
        var that=this;
        this.xhr.onreadystatechange = function () {
            if(that.xhr.readyState==4) {
                if(that.isStatusOK()){
                    clearTimeout(that.timer);
                    that.options.onSuccess(that.normalizeResponse());
                }
                else {
                    that.options.onError();
                }
                that.xhr=null;
            }
        }
    },
/*
Function: JAME.Ajax.isStatusOK
	Call by <JAME.Ajax> for internal use

Arguments:
	none.

Returns:
	void.

See also:
	<JAME.Ajax>
*/
    isStatusOK : function() {
        try {
            if((!this.xhr.status && window.location.protocol=="file:")
                || (this.xhr.status>=200 && this.xhr.status<300)
                || this.xhr.status==304 
                || (navigator.userAgent.indexOf("Safari")>=0
                   && typeof this.xhr.status==="undefined")
            ) return true;
        }catch(e){}
        return false;
    },
/*
Function: JAME.Ajax.normalizeResponse
Call by <JAME.Ajax> for internal use

Arguments:
	none.

Returns:
	void.

See also:
	<JAME.Ajax>
*/
    normalizeResponse : function() {
        var contentType = this.xhr.getResponseHeader("content-type") || -1;
        var data = (!this.options.type && contentType!=-1 && contentType.indexOf("xml")>=0);
        this.guessType();
        data = (this.options.type=="xml"||data) ? this.xhr.responseXML : this.xhr.responseText;
        if(this.options.type=="js") eval.call(window,data);
        return data;
    },
/*
Function: JAME.Ajax.guessType
	Call by <JAME.Ajax> for internal use

Arguments:
	none.

Returns:
	void.

See also:
	<JAME.Ajax>
*/ 
    guessType : function(){
        if(this.options.type)return this.options.type;
        if(/\.xml$/.test(this.options.url)) return "xml";
        if(/\.js$/.test(this.options.url))  return "js";
    },
/*
Function: JAME.Ajax.abortXHR
	Call by <JAME.Ajax> for internal use

Arguments:
	none.

Returns:
	void.

See also:
	<JAME.Ajax>
*/ 
    abortXHR : function() {
         if(this.xhr) this.xhr.abort();
         clearTimeout(this.timer);
    }
});

/*!require: JAME */

JAME.Package('JAME.Dimensions');


JAME.Dimensions = {

	windowScroll : function() {
		var d  = document,
			db = d.body,
			dd = d.documentElement,
			w  = window;
		return {
			x: w.pageXOffset || db.scrollLeft || dd.scrollLeft, 
			y: w.pageYOffset || db.scrollTop  || dd.scrollTop
		};
	},
	windowSize : function() {
		var d  = document,
			db = d.body,
			dd = d.documentElement,
			w  = window;
		return {
			height: w.innerHeight || dd.clientHeight || db.offsetHeight,
			width : w.innerWidth  || dd.clientWidth || db.offsetWidth
		};
	},
	pageSize : function() {

		var xScroll, yScroll,height,width,windowHeight,windowWidth;

		windowHeight = JAME.Dimensions.windowSize().height;
		windowWidth  = JAME.Dimensions.windowSize().width;

		if (document.body.scrollHeight > document.body.offsetHeight){ 
			xScroll = document.body.scrollWidth;
			yScroll = document.body.scrollHeight;
		} else { 
			xScroll = document.body.offsetWidth;
			yScroll = document.body.offsetHeight;
		}

		if (window.innerHeight && window.scrollMaxY) {	
			yScroll = windowHeight + window.scrollMaxY;
		}
		if (window.innerWidth && window.scrollMaxX) {	
			xScroll = windowWidth + window.scrollMaxX;
		}

		return {
			height:Math.max(yScroll,JAME.Dimensions.windowSize().height),
			width:Math.max(xScroll,JAME.Dimensions.windowSize().width)
		};
	}
};
/*!require: JAME */
JAME.Package('JAME.Util.Queue');
/*
Title: JAME.Util.Queue

Script: Queue.js
    JAME.Util.Queue - Abstract class implementing queue basic architecture

    The Queue class should be inherited by a subclass redefining its own flush/next method if necessary

Dependency:
    JAME.js

About:
    Version 0.01

Section: Constructor

Function: JAME.Util.Queue
        Constructor class	

Arguments:
    oScope - optional parameter allowing to extend the Queue class (deprecated) 

Example:
    >var myqueue = new JAME.Util.Queue();

Returns:
    a Queue instance

Section: Class Properties

Properties: paused 
- Boolean defining if the queue is paused or not

Section: Class Methods

Function: queue
        add a new entry at the end of the queue	

Arguments:
    fCallback - one or more functions to add (unlimited number of arguments)

Example:
    >myqueue.queue(function(){alert(1)},function(){alert(2)});

Returns:
    the actual instance to chain method calls

See Also:

      <dequeue>


Function: dequeue
        erase the last element in the queue	

Arguments:
    none 

Example:
    >myqueue.dequeue();

Returns:
    the actual instance to chain method calls

See Also:

      <dequeue>

Function: next
        call the next function in the queue	

Arguments:
    none 

Example:
    >myqueue.next();

Returns:
    the actual instance to chain method calls

Function: flush
        call all the functions in the queue one after an other
		the flush method should be overwritten according to your logic's need	

Arguments:
    none 

Example:
    >myqueue.flush();

Returns:
    the actual instance to chain method calls

Section: Exported functions
    none

*/

JAME.Util.Queue=function(scope) {
    this.q          = [];
    this.paused     = false;
    this._inProgress= false;
    if(scope!==undefined) JAME.extend(this,scope);
}

JAME.Util.Queue.prototype={

    queue : function() {
        for(var i=0,ln=arguments.length;i<ln;i++){
            this.q.push(arguments[i]);
		}
        return this;
    },
    dequeue : function() {
        if(!this.empty()) {
			this.q.pop();
		}
        return this;
    },
    next : function() {
        if(this.empty() || this.paused) {
            return this;
        }
        this._inProgress=true;
        this.q.shift().apply(this);
        return this;
    },
    flush : function() {
        while(!this.empty()|| !this.paused) {
			this.next();
		}
		return this;
    },
    empty : function() {
        if(this.q.length==0) {
            this._inProgress=false;
			return true;
		}
        return false;
    }
};
JAME.Util.Queue.constructor=JAME.Util.Queue;
/*!require: JAME,JAME.Util.String,JAME.CSS */
JAME.Package('JAME.FX.CSSTweener');
JAME.FX.CSSTweener = function(elm,props,frames,easing) {
	this.elm = elm;
	this.props  = props;
	this.frames = frames;
	this.easing = easing; 
	this.lookupTable={};
	var that=this;

    for(var prop in this.props){

       var method= JAME.Util.String.camelize(JAME.Util.String.firstToUpperCase(prop));

       if(this[method]) { 
		   method =	this[method];
	   }
       else if(/[0-9]+/.test(parseInt(this.props[prop].start)) && !/\s/.test(this.props[prop].end)) {
 	      method =	that.Numeric;
	   }
       else { 
		  method= that.String;
	   }
	   this.lookupTable[prop]=[this.props[prop].start,this.props[prop].end,method];
     }
}
JAME.FX.CSSTweener.prototype ={
     compute : function(frame) {
       this.frame=frame;
     
      for(var prop in this.lookupTable){

	   this.prop = prop;
	   this.from = this.lookupTable[prop][0];
	   this.to   = this.lookupTable[prop][1];
	   this.lookupTable[prop][2].call(this);
     }
  },
  String : function(obj,ratio) {
	ratio=ratio || 0.2;var set = ((this.frame/this.frames)>=ratio) ? this.to : this.from;JAME.CSS.setStyle(this.elm,this.prop,set);
  },
  Numeric : function () {
      var begin  = (/[a-z]/.test(this.from)) ? parseInt(this.from)*10000 : this.from*10000;
      var end    = (/[a-z]/.test(this.to))   ? parseInt(this.to)  *10000 : this.to  *10000;
      var displacement = this.easing(this.frame, begin, end-begin, this.frames);
	  try {JAME.CSS.setStyle(this.elm,this.prop,displacement/10000);}catch(e){};
  }
};

function QuadBezier(frame,begin,end,deviator,totalframes) {
    var t=frame/totalframes;
    return (1-t)*(1-t)*begin + 2*t*(1-t)*deviator + t*t*end;
}

JAME.Package('JAME.E4CSS');

(function() {

    var instance;

    JAME.E4CSS = function (val) {
         if (instance) {
		 	if(instance.styleSheet===-1)
		 	return instance;
			
		 }
         instance = (this instanceof JAME.E4CSS) ? this.parse(val) : new JAME.E4CSS(val);
         return instance;
    }

})();

JAME.E4CSS.prototype={

      styleSheet:0,

      sheets: (document.styleSheets) ? document.styleSheets : undefined,

      lookupTable:{},

      getCssRules : function(val) {

        if(typeof val==='number') {
            this.styleSheet=val;
            if(val > this.sheets.length) return;
            return this.sheets[val]['cssRules'] || this.sheets[val]['rules'];
        }

        var regex=new RegExp(val);

        for(i=0; i< this.sheets.length;i++) {
            if(regex.test(this.sheets[i].href)) {
                this.styleSheet=i;
                return this.sheets[i]['cssRules']|| this.sheets[i]['rules'];
            }
        }
        return undefined;
    },

    getAll : function () {
        for(i=0; i< this.sheets.length;i++)
            this.parse(i);
		this.styleSheet=-1;//loaded everything
    },

    parse : function(cssFileName) {

        if(cssFileName===undefined) {
            this.getAll();
            JAME.extend(this,JAME.E4CSS.prototype);
            return this;
        }

        var rule=this.getCssRules(cssFileName);
        if(!rule) return;

        for(var i=0;i<rule.length;i++) {

            //get the selector of first rule
            var selector=rule[i].selectorText;
            if(!selector) continue;

            //get all the attributes of above selector
            var csss=rule[i].style.cssText.split(';');

            //temporary object to hold the actual selector
            var props={};

            for(var j=0;j<csss.length;j++) {

                    //split the JAME.Util.String by :, get the attribute and value in array
                    //ie display in display: none;
                    var attr=csss[j].split(/:\s?/);

                    if(attr[0].length==1 || !attr[0] || !attr[1]) continue;

                    //lowercase the attribute as IE put all tags in uppercase
                    //and put in camel case
                    var tmp=JAME.Util.String.camelize(attr[0].toLowerCase());

                    //add the attribute with its value to the tmp obj;
                    props[JAME.Util.String.trim(tmp)]=attr[1];
            }

            //browsers are not consistent : some of them keep comma separated 
            //attributes as one selector, other change it into several one
            //therefore h1,h2{...}; can be h2 {...}; h1 {..};
            var selectors=selector.split(',') || [selector];

            for(k=0;k<selectors.length;k++) {

                //if we already have the selector in our main object
                //we add/overwrite the above values
                if(this[selectors[k]]) {
                    for(var attr in props)
                        this[selectors[k].toLowerCase()][attr]=props[attr];
                }
                //if the selector is not in the main object,
                // we just add the temporary object into it
                else 
                    this[selectors[k].toLowerCase()]=props;	

                // we keep track from where the selector comes, ie the style sheet number
                this.lookupTable[selectors[k].toLowerCase()]=this.styleSheet;
            }
        }

        return this;
    }
};

/*!require: JAME,JAME.Util.Queue,JAME.Events,JAME.FX.CSSTweener,JAME.E4CSS,JAME.CSS */
JAME.Package('JAME.FX');


/* JAME.load('JAME.Util.Queue','JAME.Events','JAME.FX.CSSTweener','JAME.E4CSS','JAME.CSS.Property'); */


/*
Title: JAME.FX - Special Effects for the rest of us!

Script: FX.js
	JAME.FX - animate the DOM easily

*/

/*

Section: Core class description 

Function: JAME.FX.Tween

	specify elments to animate, css properties to animate and general settings


Arguments:
	oHTMLElement || Array oHTMLElement - an HTML object or an array of HTML objects
	hCSS						 	   - an hash containing the style to animates
	hSettings						   - an hash to modify the default behavior of the animation

Example:
	
	a) Settings of css properties in javascript
		
	(start code)
	var myfx = new JAME.FX.Tween(
		[JAME.$("contents"),JAME.$('contents2')],
		{
			opacity: [0,1],
			padding: ["0px 0px 0px 0px","12px 4px 2px 1px"],
			border : ["1px solid #000000","3px dashed #FF0000"],
			height : 60,
			zIndex : [1,300],
			width  : 350
			'font-size' : 24,
			backgroundPosition:["0px 30px","45px 0px"]
		},
		//default settings:
		{
			duration : 700,
			fps		 : 40,
			behavior : 'stop:link',
			easing   : JAME.FX.Transition.Linear,
			async	 : false,
			string	 : 0.5
		});
	> myfx.addListener('onComplete',function() {
			alert('end');
	  }).queue(function() {
		  alert('chaining effect is easy too');
	  });
	(end)
	
	The constructor expects an html object or an array of html objects as the first parameter.
	
	The second parameter must be an hash supplying a list of css properties as keys and their value to manipulate.
	Both camelCase and usual css spelling are accepted (zIndex or z-index) for the css properties.
	The values of the hash accept either an array or one value (Number,String or Array with one value).
	The first value of the array is the start end the second value is the end value of the animation.
	If you specify only one value, it will be considered the end value of the animation
	and JAME will look for the actual computed value of the element. If no value is already set, an error might occur.
	The following css properties are accepted:
	- All css properties that contains only one integer/float value
	- All css properties that contains only one string value
	- Built in extensions for padding, margin,background-position,border,etc exist
	  but one can easily create an extension for a css property that is not supported yet (TODO:explain how)
	
	If you do not specify a unit, pixel will be assumed and is the only unit available.
	
	The third parameter is optional, you can overwrite default settings if necessary:
	- duration: set the duration of the animation in ms
	- fps	  : frame per second. The higher the smoother. 
	            The fps is dynamic and will be changed according the capacities of the host.
	- behavior : 4 different behaviors are available now:
		-
	- easing :many different easing functions are available see the JAME.FX.Transition package.
	- async : if you set an array of html objects, each element will be animated one after an other by default.
	If you set the async value to true, the elements will be animated all together.
	- string : specify the ratio of time to which a string value should be switched
	For example, if you set an animation to last 1000ms with a borderStyle switching from line to dashed,
	by default the switch will happen at 500ms.	
	
Returns:
	JAME.FX object
		
Section : Supported events


	

*/

JAME.FX.Tween = function(elm,props,option){
	
		this.setOptions(option);
		
        if(arguments[3]) this.paused=true;
		JAME.extend(this,new JAME.Util.Queue());
		JAME.extend(this,new JAME.Events.EventDispatcher());
        this.elm= elm || this.elm;

        this.props = props || this.props;
		this.setMultiInstance(arguments[3]);
        this.setProperties();

        if((elm && props) || !this.tweener) 
           this.tweener = new JAME.FX.CSSTweener(this.elm,this.props,this.totalframes,this.easing);

        if(!this.setBehavior())return this;

        this.elm.__ON  = true;
        this.startingTime  = new Date().getTime();
        var that= this;
        this.elm.effect = that;
        this.dispatch('onStart');
        this.timer = setInterval(function() {
            that.setAnimation.apply(that)
        },this.interval);
        return this;
}

JAME.FX.Tween.prototype = {
	setOptions : function(option){

    	option = option || {};
    	this.duration  = option.duration || 700;
    	this.fps       = option.fps      || 40;
    	this.easing    = option.easing   || function(t,b,c,d) { 
                                          return b + (c/d)*t;
                                        };
    	this.async       = option.async || false;
    	this.behavior    = option.behavior || 'stop:link';

    	this.interval    = Math.ceil(1000/this.fps);
    	this.totalframes = Math.ceil(this.duration/this.interval);
    	this.frame       = 1;	
	},
    setAnimation : function() {

         this.actualTime = new Date().getTime();
         this.tweener.compute(parseInt( (this.actualTime - this.startingTime) / this.interval));
         this.dispatch('onTween');
         if(this.actualTime >= this.startingTime + this.duration)
             this.stop();
    },
    setProperties : function() {

        for(var method in this.extendProperties) {
             if(method=='prototype') continue;
             this.extendProperties[method].apply(this);
        }
    },
    reverse : function() {

        var props = this.props;

        for(var prop in props) {
          var end =this.props[prop][1];
          this.props[prop][1]=this.props[prop][0];
          this.props[prop][0]=end;
        }
        this.elm = (this.elms && this.elms.length) 
                 ? this.elms.reverse() 
                 : this.elm;
        JAME.FX.Tween.call(this,this.elm,this.props,this);
    },
    stop : function() {
         clearInterval(this.timer);
         this.tweener.compute(this.totalframes);
         this.paused=false;
         this.elm.__ON = false;
         this.dispatch('onComplete');
		 this._cleanOut();
         this.next();
         return this;
    },
	_cleanOut : function(){
		 this.elm.effect = null;
		 this.elm.__ON   = null;
	},
    addToQueue : function (that) {
        var me =this;
        that.queue(function () {
           return JAME.FX.Tween.call(that,me.elm,me.props,me,1);
        });			
    },
    setBehavior : function() {

      if(this.elm.__ON===true) {
         var that=this.elm.effect;
        
         if(this.behavior=='stop:link') { 
      
           var actualProps=that.props;
           for (var prop in actualProps) {
              if (this.props[prop])
                this.props[prop][0] = that.elm.style[prop];
           }
           if(this.empty()) this.addToQueue(that);
           that.stop();
           return;
        }
        else if(this.behavior=='stop:play'){
          clearInterval(that.timer);
          this.q=[];
          return true;
        }
        else if(this.behavior=='finish:play' || this.behavior=='finish:link') {
          this.addToQueue(that);
          return;
        }
        else if(this.behavior=='finish:skip') {
          return;
        }
        else {
		  this._cleanOut();
          clearInterval(that.timer);
          this.q=[];
          return;		
        }
      }
      return true;
    },
    setMultiInstance : function () {

      var arg=arguments[0];

      if(this.elm && this.elm.constructor===Array) {

           this.elms=this.elm;

           var that=this;
           if(this.async) {
              for(var i=1;i<this.elm.length;i++) {
                 (function() {
                     var elm=that.elm[i];
                     JAME.FX.Tween.call(that,elm,that.props,that);
                    })();
               }
           }
           else {

            if(arg===undefined) {
               for(var i=1;i<this.elm.length;i++) {
                  (function() {
                     var elm=that.elm[i];
                     that.queue(function () {
						JAME.FX.Tween.call(that,elm,that.props,that);
                     });
                   })();
               }
            }
            else {

              for(var i=this.elm.length-1;i>0;i--) {
                (function() {
                   var elm=that.elm[i];
                   that.q.unshift(function () {
                     JAME.FX.Tween.call(that,elm,that.props,that);
                   });
                 })();
              }
              if(arg) that.paused=false;
           }
           this.elm=this.elms[0];
          }
    }
   }
};

JAME.FX.Tween.prototype.extendProperties={

        CSS  : function() {


            if(this.props['selector']) {

               var style = (this.props['selector'][2]) ? this.props['selector'][2] : 0;
               if(this.style!=style) {
                    this.style=style;
                    var css    = new JAME.E4CSS(style);
                    var starts = css[this.props['selector'][0]];
                    var ends   = css[this.props['selector'][1]];
                    for(var prop in starts)  {
						this.props[prop]={};
						this.props[prop]["start"]=starts[prop];
						this.props[prop]["end"]  =ends[prop];
					}
               }
               delete this.props['selector'];
           }
       },
        Auto : function() {

            var nprops={};
            for(var prop in this.props) {
                nprops[prop]={};
				var type = this.props[prop].constructor;
                if (type===String||type===Number) {
                    nprops[prop]["end"]    = this.props[prop];
                    nprops[prop]["start"]  = type===Number ?parseFloat(JAME.CSS.getStyle(this.elm,prop)):JAME.CSS.getStyle(this.elm,prop);
					continue;
                }
                if (this.props[prop].length == 1) {
                    nprops[prop]["end"]  = this.props[prop][0];
                    nprops[prop]["start"] = JAME.CSS.getStyle(this.elm,prop);
					continue;
                }
                if (this.props[prop].length == 2) {
                    nprops[prop]["start"] = this.props[prop][0];
                    nprops[prop]["end"]  = this.props[prop][1];
					continue;
                }
                if (!this.props[prop].length) {
                    nprops[prop]["start"] = this.props[prop]["start"];
                    nprops[prop]["end"]  = this.props[prop]["end"];
                }
            }
            this.props=nprops;
			nprops=null;
       }
};

/*
JAME.FX.Tween.Garbages=[];
JAME.FX.Tween.GarbageCollector=function() {
    for(var i=0;i<JAME.FX.Tween.Garbages.length;i++)
            JAME.FX.Tween.Garbages[i]=null;
}
JAME.FX.Tween.Export = function() {
     JAME.Exporter({'Tween':JAME.FX.Tween});
}

*/
/*!require: JAME,JAME.Dimensions,JAME.Browser,JAME.Events,JAME.FX */
JAME.Package('JAME.Components.Overlay');

new function () {

var	Dimensions = JAME.Dimensions,
//event listener need some help in ie
	resizeLock = 0,
//overlay is a singleton
    instance   = undefined;

JAME.Components.Overlay = function(options) { 
		if(!instance)
			instance = this;
		instance.init(options)
		return instance;
};
JAME.extend(JAME.Components.Overlay.prototype,new JAME.Events.EventDispatcher());


var Overlay    = JAME.Components.Overlay;

JAME.extend(JAME.Components.Overlay.prototype, {

	whiteBackground : {
		image :"url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAARUlEQVRo3u3PMREAAAgEIO0fx4BvBlcPGtBJph5oEREREREREREREREREREREREREREREREREREREREREREREREREZGLBagruJMIJCR+AAAAAElFTkSuQmCC')",
		code  :'#ffffff'
	},

	blackBackground : {
		image:"url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEhJREFUeNrszzERACAMALEH/25qEBcMvcRBTjUtcFtCRERERERERERERERERERERERERERERERERERERERERERERERE5I8nwABEjQEXuO95jAAAAABJRU5ErkJggg')",
		code :'#222222'
	},

	getOverlayIndex : function() {
		return this.overlay.style.zIndex;
	},

	defaultValue : {
		color:Overlay.prototype.blackBackground,
		effect: {
			duration:400
		}
	},

	init:function(options) {
		var d = this.defaultValue;
		JAME.extend(d,options||{});
		this.options = d;
		this.createOverlay();
	},

	_setOverlaySize : function () {
		this.windowsize       = Dimensions.windowSize();	

		JAME.CSS.setStyles(this.overlay,{
			width  : this.windowsize.width,
			height : this.windowsize.height
		});
		this.page       = Dimensions.pageSize();	

		JAME.CSS.setStyles(this.overlay,{
			width  : this.page.width,
			height : this.page.height
		});
		if(this.hidden){
			JAME.CSS.setStyles(this.overlay,{
				top    : -1*this.page.height
			});
		}
		this.dispatch('onResize',{wwidth:this.page.width,wheight:this.windowsize.width,pwidth:this.windowsize.width,pheight:this.windowsize.height});
	},
	_setOverlayColor : function () {

		//mozilla on mac has a problem with opacity and flash
		//we use the encode 64 image png data instead
		if(JAME.Browser.Engine.gecko && JAME.Browser.Platform=='mac'){
			JAME.CSS.setStyles(this.overlay,{
				backgroundImage:this.options.color.image
			})
		} 
		else {
			JAME.CSS.setStyles(this.overlay,{	
				backgroundColor: this.options.color.code,
				opacity:.85
			})				
		}
	},

	createOverlay : function() {

		if(JAME.$('jame_overlay')){
			return instance;
		}

		this.overlay    = JAME.DOM.createNode('div');
		this.overlay.id = 'jame_overlay';


		JAME.CSS.setStyles(this.overlay,{
			position:'absolute',
			left:0,
			zIndex:100000
		});

		this._setOverlaySize();

		JAME.CSS.setStyles(this.overlay,{
			top    : -1*this.page.height
		});

		this._setOverlayColor();

		document.body.appendChild(this.overlay);
		this.hidden = true;
		var self    = this;
		JAME.Events.addListener(window,'resize',function() {self.resizeListener()});
	},

	displayOverlay : function() {
		if(!this.hidden)
			return false;
		var self     = this,
		    duration = this.options.effect.duration;
		if(JAME.Browser.Engine.trident){
			Overlay.prototype.toggleHTMLElements();
		}

		self.dispatch('onBeforeDisplay');
		new JAME.FX.Tween(this.overlay,{top:[0]},{duration:duration}).queue(function() {
			self.hidden = false;
			self.dispatch('onAfterDisplay');
		})
	},

	hideOverlay : function() {
		if(this.hidden)
			return false;
		var self     = this,
		    duration = this.options.effect.duration;
		self.dispatch('onBeforeHide');
		new JAME.FX.Tween(this.overlay,{top:[-1*this.page.height]},{duration:duration}).queue(function() {
			self.hidden=true;
			self.dispatch('onAfterHide');
		})
	},

	resizeListener : function () {
		var self = this;
 		if (!resizeLock++) {
    		setTimeout(function() {		
				self._setOverlaySize();
      			setTimeout(function() { resizeLock = 0; }, 0);
    		}, 0);
  		}
	},

	toggleHTMLElements : function(visibility) {
		var body = document.body;
		var selects = body.getElementsByTagName('select');	
		for(var i =0,ln=selects.length;i<ln;i++){
			selects[i].style.visibility= visibility ||'hidden';
		}
	}
});

}
/*!require: JAME,JAME.Events,JAME.CSS,JAME.Ajax,JAME.Dimensions,JAME.Components.Overlay */
JAME.Package('JAME.Components.ModalWindow');

JAME.Components.ModalWindow = function (options) {

	//lazy extension
	if(!JAME.Components.ModalWindow.extended){
		JAME.extend(JAME.Components.ModalWindow.prototype,new JAME.Events.EventDispatcher());
		JAME.Components.ModalWindow.extended=true;
	}
	this.init(options);
};

new function () {

	var jcm       = JAME.Components.ModalWindow;
	var jco		  = JAME.Components.Overlay;
	jcm.instances = 0;

JAME.extend(JAME.Components.ModalWindow.prototype, {

	init: function(options) {
		this.options			 = options;
		this.hidden		         = true;
		this.overlay 		     = new jco({color:options.overlayColor || jco.prototype.whiteBackground});
		this._setupModalWindow();
	},

	_setupCloseBtnListener : function () {
		JAME.Events.addListener(this.closeBtn,'click',function() {
			this.hide();
		},this)
	},

	hide : function () {
		var self = this;

		//we do both animations at the same time
		this.overlay.hideOverlay();
		new JAME.FX.Tween(this.wcontainer,{top:[-1000]}).queue(function() {
			self.body.innerHTML  = '';
			self.title.innerHTML = '';
			self.dispatch('onModalWindowHidden');
		});
	},

	_setWindowPosition : function (isInit) {
		var windowsize = JAME.Dimensions.windowSize();
		//centered window only for now
		//no resizing to fit the actual window size
		var width  =  (isInit) ? 150 : this.options.width;
		var height =  (isInit) ? 150 : this.options.height;

		JAME.CSS.setStyles(this.wcontainer,{
			left   : windowsize.width  / 2  - width  / 2,
			top    : (this.overlay.hidden) ? -1000 : windowsize.height / 2  - height / 2
		});
		return windowsize;
	},

	_setupModalWindow : function () {
		var self            	   = this;

		this.instance  			   = jcm.instances++;
		this.wcontainer     	   = JAME.DOM.createNode('div');
		this.wcontainer.id         = "jame_window_id"+this.instance;
		this.wcontainer.className  = "jame_window";
		this.wcontainer.innerHTML  = '<div class="jame_window_header">'+
										'<span class="jame_window_close_button">x</span>'+
										'<h2 class="jame_window_title"></h2>'+
									'</div>'+
									'<div class="jame_window_body"></div>';
		this._initDefaultStyle();
		document.body.appendChild(this.wcontainer);	
 		this._setWindowPosition(1);
		this._setUpLookup();
		this._setupCloseBtnListener();
		this.overlay.addListener('onAfterDisplay',function(){self._displayModalWindow()});
		this.overlay.addListener('onResize',function(){self._setWindowPosition()});
	},

	display : function (options) {
		if(options) {
			this.options = options;
		}
		this.overlay.displayOverlay();
	},

	_initDefaultStyle : function () {

		JAME.CSS.setStyles(this.wcontainer,{
			position: 'absolute',
			width   : 150,
			height  : 150,
			'-moz-box-shadow'    : '0 0 35px 5px #222',
			'-webkit-box-shadow' : '0 0 35px #222',
			'box-shadow' : '0 0 35px 5px #222',
			zIndex               : this.overlay.getOverlayIndex()+1
		});
	},

	_displayModalWindow : function () {
		var self       = this;
		this._initDefaultStyle();
 		var windowsize = this._setWindowPosition(1);
		new JAME.FX.Tween(this.wcontainer,{
			width : [this.options.width],
			left  : [windowsize.width  / 2  - this.options.width  / 2]
		},{duration:400}).queue(function() {

			new JAME.FX.Tween(self.wcontainer,{
				height: [self.options.height],
				top   : [windowsize.height / 2  - self.options.height / 2]
			},{duration:400}).queue(function() {
				self.dispatch('onModalWindowDisplay');
			});

			self._insertData();
		})
	},

	//only ajax for now...
	//external urls might be implemented later
	_insertData : function () {
		var self = this;

		new JAME.Ajax({
			url:this.options.url,
			onSuccess: function(resp){
				self.setBody(resp);
				self.setTitle(self.options.title);
				self.dispatch('onSuccess',resp,self.body);
			}
		})
	},

	_byTag: function(tag) {
		return this.wcontainer.getElementsByTagName(tag);
	},

	_setUpLookup : function() {
		//shortcuts to avoid unnecessary lookups:
		this.title     = this._byTag('h2')[0];
		this.body      = this._byTag('div')[1];
		this.closeBtn  = this._byTag('span')[0];
	},
	setTitle : function (title) {
		this.title.innerHTML   = title || '';
	},
	setBody : function (body) {
		this.body.innerHTML    = body || '';
	}

});

}

