/*
**********************************
* GetMyWeb main js script
**********************************

Copyright (c) 2007 Mathieu Goessens <gebura@evilkittens.org> 

Permission to use, copy, modify, and distribute this software for any 
purpose with or without fee is hereby granted, provided that the above 
copyright notice and this permission notice appear in all copies. 

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 

**********************************

Most of this work wasn't possible without Mike foster's X library,
If you read this code, please have a look on http://cross-browser.com/x/
*/

/***********************************
	    Configuration
************************************/

// Timeout Ajax (milisec)
var AJAXTIMEOUT = 30000;


// How many time we print the mask
var MASKTIME = 2500;


// Default (starting) box width and height
var BOXWIDTH = 600;
var BOXHEIGHT = 400;

// Default (starting) box positon (x and y)
var BOXPOSX = 50;
var BOXPOSY = 50;


// How many time (in milisec) we wait before displaying infobox (help box, detail box...)
var INFOBOX_TIMER = 300;

// How many time (in milisec) is the infobox's animation (opacity) durring
var INFOBOX_ANIMTIME = 700;

// Integer margin around menu. when mouse is outside this margin the menu is hid.
var MENU_DIST = 50;

// If you put the infobox just under mouse, creator_element.onMouseOver = unshowInfoBox() may be run
// So we just put the box with a few px difference, how many ?
var INFOBOX_PXDIFFX = 0;
var INFOBOX_PXDIFFY = 20;


// Random length
var RANDOMLENGTH = 1000;

// When saving, negative numbers (like height or position) will be remplaced by this number further problem when displaying
DEFAULTNUMBER = 200;

/******************************
	Chargement...
*******************************/

// may be we can use xAddEventLister(), but is this very usefull ?
window.onload = function ()
	{
	new xMenu1("AddModuleLink", "AddModuleMenu", MENU_DIST, "mouseover");
	new xMenu1("GetmywebLink", "GetMyWebMenu", MENU_DIST, "mouseover");
	gmwCreateAllBox();

	gmwPutLoadMsgOn("masque");
	gmwUnShowMasque();

	}

/******************************
	Fermeture...
*******************************/

window.onunload = function ()
	{
	gmwSaveAllBox(false);
	}



/************************************
	Fonctions utilitaires
************************************/

function xGetAlt(e)
	{
	return xGetElementById(e).getAttribute("alt");
	}

function xToggle(e)
	{
	if (xDisplay(e)=="none")
		{
		xDisplay(e,"");
		}
	else
		{
		xDisplay(e,"none");
		}
	// Unsure that the link will'nt be followed when click on a <a href
	return false;
	}

function gmwPutLoadMsgOn(element)
	{
	xInnerHtml(element,xInnerHtml("message"));
	}

function xRandom()
	{
	return Math.round(Math.random() * RANDOMLENGTH);
	}

function gmwDefaultNumber(n)
	{
	if (n <= 0)
		{
		n = DEFAULTNUMBER;
		}
	return n;
	}
/************************************
	 Gestion des Fenetres
************************************/

function gmwCreateBox(idbox,typebox,posxbox,posybox,widthbox,heightbox,url)
	{

	// Creation elements.
	if (url!=null && url!="")
		{
		divFenetre = document.createElement("iframe");
		}
	else 
		{
		divFenetre = document.createElement("div");
		}
	divFenetre.id=idbox;
	divFenetre.className="xFenster";
	xGetElementById("content").appendChild(divFenetre);

	// Creation fenetre
	return new xFenster(idbox, "GMW: Module "+ typebox, (url || ""), parseInt(posxbox), parseInt(posybox), parseInt(widthbox), parseInt(heightbox), true, true, true, true, null, null, null, null, null);
	// (clientId, iniTitle, iniUrl, iniX, iniY, iniW, iniH, enMove, enResize, enMaxRes, enClose, fnMove, fnResize, fnMaxRes, fnClose, fnFocus)
	}

function gmwCreateAllBox()
	{
	// Listage onglets
	// (onglets is a var acquired in json format by using <script src="somephpscript.php"> check html file for more...

	xEach(	onglets,
		function (item,index,number)
			{
			
			//Listage boites
			xEach(	item["boxes"],
 				function (item2,index2,number2)
 					{
					gmwCreateBox(item2["idbox"], item2["typebox"], item2["posxbox"], item2["posybox"], item2["widthbox"], item2["heightbox"] );
					
					// Maybe could we use gmwDoForAllBox(function) but it will list box another time.
					gmwSetBoxContent(item2["idbox"],item2["typebox"],"consult",null)
 
					}
				)
			}
		)
	}

function gmwSetBoxContent(idbox,typebox,mode,param)
	{
	
	gmwPutLoadMsgOn(idbox);
	// Unsure mode is correctly setted
	if ( (mode != "consult") && (mode != "edit") && (mode != "exec" ) )
		{
		mode = "consult";
		}

	url="../modules/"+ typebox +"/php/"+ mode +".php";

	// add param only if needed
 	param = "idbox="+ idbox + ( (param!=null) ? "&" + param : "");

	gmwAJAXReq(url,param,function (req){ xInnerHtml(idbox,req)  });

	// Unsure that the link will'nt be followed when click on a <a href
	return false;

	}


function gmwCreateBrowserBox(url,max)
	{
	random = xRandom();

	//Prevent that random can be equal to an existing box id.
	while (xGetElementById(String(random))!=null){
		random = xRandom();
		}
	box = gmwCreateBox(String(random),"navigateur",BOXPOSX,BOXPOSY,BOXWIDTH,BOXWIDTH,url);
	box.focus();

	// IDEA: not use max, but have a param like "optimal" witch will get iframe content size and resize box for having an optimal displaying
	// We can do this with box.client objet and a modification of xClientWidth() or  by using Element.offsetHeight.
	if (max)
		{
		box.maximizeOrUn(); // this function require Patched xFenster ,be carrefull !
		}
	
	// Unsure that the link will'nt be followed when click on a <a href
	return false;
	}

function gmwDoForAllBox(funct)
	{
	// the listing function is from xFenster source
	var i, o = xFenster.instances;
	for (i in o)
		{
		if (o.hasOwnProperty(i))
			{
			funct(xFenster.instances[i],i);
			}
		}
	}

// Synchronize onglets witch contain box informations with actual information (size...)
function gmwSyncBox(idbox,posx,posy,width,height)
	{
	//	We could use an accessor style function for this BUT the problem is that for every property we will get,
	//	we will browse another time the objets, so we choose to use a code like this, even more complex,
	//	it must be more performant
	xEach(	onglets,
		function (item,index,number)
			{
			//Listage boites
			xEachUntilReturn( item["boxes"],
				function (item2,index2,number2)
					{

					if (item2["idbox"]==idbox)
						{
						item2["posxbox"]=gmwDefaultNumber(posx);
						item2["posybox"]=gmwDefaultNumber(posy);
						item2["widthbox"]=gmwDefaultNumber(width);
						item2["heightbox"]=gmwDefaultNumber(height);

						// xEachUntilReturn() Stop when launched function return a value
						// So it act like a "break"
						return true;
						}
					}
				)
			}
		)
	}

function gmwSaveAllBox(redirect)
	{
	if (redirect==null)
		{
		redirect=true;
		}

	gmwDoForAllBox( function (BoxInst,idbox)
		{
		gmwSyncBox(idbox, xLeft(BoxInst.con) , xTop(BoxInst.con) , BoxInst.conW, BoxInst.conH);
		}
		)
	// remove gmwSaveAllBox() from on unload because it can prevent changing location
	window.onunload = function (){};
	document.location = "saveongletsinfo.php?redirect="+ redirect +"&onglets=" + escape(onglets.toJSONString());
	}

function gmwReloadAllBox()
	{
	gmwDoForAllBox( function (obj,i)
		{
		// Show only box with a div content (not iframe, so not the browser box)
		if ( (obj.client.tagName=="DIV") || (obj.client.tagName=="div") )
			{
			obj.show();
			}
		}
		)	
	}

function gmwAddBox(typebox,idonglet,idbox)
	{
	gmwCreateBox(idbox, typebox, BOXPOSX, BOXPOSY, BOXWIDTH, BOXHEIGHT, null);
	gmwSetBoxContent(idbox, typebox, "edit", null);

	gmwUpdateOngletsInfo();
	}

function gmwDestroyBox(idbox)
	{
	// there isn't accent here because if firefox are displaying there well, ie doesn't and it print html entitys (like &eacute;)
	if (window.confirm("Voulez vous vraiment detruire ce module et ses parametres?"))
		{
		gmwAJAXReq("destroymodule.php", "idbox="+idbox, function (){ gmwUpdateOngletsInfo(); });

		gmwDoForAllBox(function (obj)
			{
			if (obj.client.id==idbox)
				{
				obj.hide();
				obj=null;
				}
			}
			)
		}
	return false;
	}

function gmwUpdateOngletsInfo()
	{
	var onglets = null;
	// reevalute the "onglets" objet
	gmwAJAXReq("ongletsinfo.php", null, eval)
	}

function gmwRequestNewBox(typebox,idonglet)
	{
	gmwAJAXReq("addmodule.php", "typebox="+typebox+"&idonglet="+idonglet, function (content){ gmwAddBox(typebox,idonglet,content); });
	}


/************************************
		AJAX
************************************/



function gmwAJAXReq(url,param,callback)
	{
	var request = new xHttpRequest();

	request.send('GET', //method
		url, // Url
		param, //params
		AJAXTIMEOUT, // timeout (millisec)
		false, // Put a random in request params
		false, // the response is expected to be XML
		null, // objet to put in params
	
		function (req, status, obj)
			{
			// If request has work well
			if (status==request.OK)
				{
				// launch Callback function put in params with content of response.
				callback(req.responseText);
				}			
			// Else (if there were a problem)
			else {
				// TODO: Modify: use mask ? use a message div ?
				alert('Erreur de communication avec le serveur');
				}
			} //End anonymous function
		); // end request.send param list
	}


/************************************
	    Formulaires
************************************/

function gmwDoSearch(form)
	{
	return gmwSendForm(form)
	}

function gmwConcatInputsValues(form)
	{
	var values="";

	for (x=0; x<form.elements.length; x++)
		{
		// Like gmwSendForm(f) but don't concat idbox witch will be send by an other way (cf gmwSetBoxContent())
		if (form.elements[x].name !="idbox") 
			{
			// We also send only some type of input (not submit and button for example)
			if ( (form.elements[x].type =="checkbox") || (form.elements[x].type =="radio") )
				{
				// And for some input, we don't send value if there aren't checked
				if ( (form.elements[x].checked==true) || (form.elements[x].checked=="checked") )
					{
					values+=form.elements[x].name + "=" + escape(form.elements[x].value) +"&";
					}
				}

			// Firefox and ie use select-one has for input like <select>, test with type=="select"
			// has been keep for compatiliby but isn't very usefull for now
			if ( (form.elements[x].type =="text") || (form.elements[x].type =="hidden") || (form.elements[x].type =="select") || (form.elements[x].type =="select-one") || (form.elements[x].type =="textarea") )
				{
				values+=form.elements[x].name + "=" + escape(form.elements[x].value) +"&";
				}
			}
		}
	return values;
	}

function gmwSendForm(form){
	url = form.action;

	for (x=0; x<form.elements.length; x++)
		{
		if (x==0)
			{
			url += "?";
			}
		else
			{
			url += "&";
			}

		if ( (form.elements[x].type !="submit") && (form.elements[x].type !="button") )
			{
				url+= form.elements[x].name + "=" + escape(form.elements[x].value);
			}
		}
	gmwCreateBrowserBox(url);

	// Unsure that the form willn't be realy submited.
	return false;
	}



/************************************
	Gestion des infoboxs
************************************/

var InfoBoxTimer;

function gmwShowInfoBox(event,txtContent,txtDesc)
	{
	var element = element;
	var e = new xEvent(event);

	var diff = 25;

	InfobulleTimer = setInterval( function ()
		{
		xOpacity("infobox",0);
		xLeft("infobox", e.pageX + INFOBOX_PXDIFFX );
		xTop("infobox", e.pageY + INFOBOX_PXDIFFY);

		xInnerHtml("infobox-content",txtContent);
		xInnerHtml("infobox-desc",txtDesc);

		xDisplay("infobox","");
		xAniOpacity("infobox", 1, INFOBOX_ANIMTIME, 2, null);
		clearTimeout(InfobulleTimer);
		},
	INFOBOX_TIMER);
	}


function gmwHideInfoBox()
	{
	clearTimeout(InfobulleTimer);
	xDisplay("infobox","none");
	xInnerHtml("infobox-content","");
	xInnerHtml("infobox-desc","");
	}

/************************************
	Gestion de l'aide
	(et clones...)
************************************/

function gmwShowHelp(event,element)
	{
	// TODO:if (user.help)
	if (true)
		{
		if (xGetAlt(element).length!=0)
			{
			gmwShowInfoBox(event,xGetAlt(element),"Aide:<br />");
			}
		}
	}


function gmwHideHelp()
	{
	// TODO: if (user.help)
	// not necessary bot prevent usage of not needed code
	if (true)
		{
		gmwHideInfoBox();
		}
	}


function gmwShowDetails(event,element)
	{
	if (xGetAlt(element).length!=0)
		{
		gmwShowInfoBox(event,xGetAlt(element),"Details:<br />");
		}
	}


function gmwHideDetails()
	{
	gmwHideInfoBox();
	}

/******************************
	Gestion du masque
*******************************/

function gmwShowMasque(msg)
	{
	xDisplay("masque","");
	xOpacity("masque",0);
	xInnerHtml("masque",( ("<p>"+ msg +"</p>") || ""));
	xAniOpacity("masque", 1, MASKTIME, 1, null);
	}

function gmwUnShowMasque()
	{
	xOpacity("masque",1);
	xAniOpacity("masque", 0, MASKTIME, 1, null);

	var MasqueTimer = setInterval( function () { xDisplay("masque","none"); clearTimeout(MasqueTimer) },MASKTIME+250);
	}
