//Standard simple wrapper for event listeners and their
//different implementations in I.E. and the rest of the world
function addEvent(elementObject, eventName, functionObject)
{
	if(document.addEventListener)
		elementObject.addEventListener(eventName, function (evt){ functionObject(elementObject, evt) }, false);
	else if(document.attachEvent)
		elementObject.attachEvent("on" + eventName, function () { functionObject(elementObject);})
}

var StoredEvents = Array();

//Given a scriptaculous event, adds it to the specified group
//This is so you can reference them later
function storeEvent(passevent, groupnum)
{
	if (StoredEvents[groupnum] == undefined) StoredEvents[groupnum] = Array();
	
	StoredEvents[groupnum][StoredEvents[groupnum].length] = passevent;
}

//Stop all stored events of a certain group by calling their destroy function
function stopStoredEvents(groupnum)
{
	if (StoredEvents[groupnum] != undefined)
	{
		for(var i = 0; i < StoredEvents[groupnum].length; i++)
		{
			StoredEvents[groupnum][i].destroy();
		}
		StoredEvents[groupnum].length = 0;
	}
}

function GetElementY(oElement)
{
	var iReturnValue = 0;
	while( oElement != null )
	{
		iReturnValue += oElement.offsetTop;
		oElement = oElement.offsetParent;
	}
	return iReturnValue;
}

function GetElementX(oElement)
{
	var iReturnValue = 0;
	while( oElement != null )
	{
		iReturnValue += oElement.offsetLeft;
		oElement = oElement.offsetParent;
	}
	return iReturnValue;
}

//Array to hold the info on forms being sent
//over a transport request
var JSForms = Array(5);
var JSFormsActive = false;

//Takes the following:
//URL to submit to
//Name of form to submit
//ID of div to put response text in
//optional callback, gets called when the request completes *successfully*
//optional array with messages:
//	StartMSG (1)
//	FailureMSG (2)
//	TimeoutMSG(3)
//Note: only one submission at a time
//If a second is given, and error is put in the
//msgid given and no other action is taken
//There is an expected submit button called Submit
function JSSubmitForm(url, formname, msgid, messages, callback, reloadsb)
{

	if(JSFormsActive == true)
	{
		ChangeMSG(msgid, "<div class='ErrorText'>A different form is processing..</div>");
	}
	else
	{
		if (messages == undefined) messages = new Array(4);
		if(messages[1] == undefined) messages[1] = 'Form submitted, waiting for response...';
		if(messages[2] == undefined) messages[2] = "<div class='ErrorText'>The request failed! Changes not saved.</div>";
		if(messages[3] == undefined) messages[3] = "<div class='ErrorText'>Timeout error! Changes not saved.</div>";

		JSForms[0] = url;
		JSForms[1] = formname;
		JSForms[2] = msgid;
		JSForms[3] = messages;
		JSForms[4] = callback;
		JSForms[5] = reloadsb;
		JSFormsActive = true;

		//We do this do the form doesn't submit on us
		//While we are doing stuff below
		setTimeout("JSFormStart()", 10);
	}

	//Return false so the form doesn't get submitted
	//Through normal methods, in case this was called from
	//an onSubmit
	return false;
}

function JSFormStart()
{
	ChangeMSG(JSForms[2], JSForms[3][1]);

	if($(JSForms[1]).Submit != undefined)
		$(JSForms[1]).Submit.value="Processing";

	new Ajax.Request(JSForms[0],
	{
		method:'post',
		onSuccess: JSFormSuccess,
    		onFailure: JSFormFailure,
		onTimeout: JSFormTimeout,
		parameters: $(JSForms[1]).serialize(true)
	});

	$(JSForms[1]).disable(true);
}

function JSFormSuccess(transport)
{
	ChangeMSG(JSForms[2], transport.responseText);

	if($(JSForms[1]).Submit != undefined)
		$(JSForms[1]).Submit.value="Submit";
	$(JSForms[1]).enable();
	if(JSForms[4] != undefined) JSForms[4](transport);
	JSFormsActive = false;

	//Any time we might have made changes - reload the current Subject in the browser
	if (JSForms[5] == undefined || JSForms[5] == true)
		ReloadCurrentSubject();
		
	//Hackity... but need to disable authors editing if they arn't available
	if (SelectedAuthorsIDs.length == 0) DisableThingsThatNeedAuthors();
}

function JSFormFailure(transport)
{
	ChangeMSG(JSForms[2], JSForms[3][2]);

	if($(JSForms[1]).Submit != undefined)
		$(JSForms[1]).Submit.value="Submit";
	$(JSForms[1]).enable();
	JSFormsActive = false;
}

//Queue up a short duration message
function ChangeMSG(msgid, msg)
{
	//Because we may wish multiple messages to be changing at the same time, but can not allow
	//a message for a specific ID to be doing multiple changes at once (we want them properly queued)
	//Try to extract a string of the ID of msgid
	var msgscope = "ChangeMSG";
	if (msgid.id != undefined)
		msgscope = msgid.id;

	//If there is another message, then fade it, and as soon as that finishes add the new one
	if (msgid.innerHTML != "&nbsp;")
	{
		new Effect.Fade(msgid, {queue: {position:"end", scope: msgscope}, duration:0.4, afterFinish: function()
		{
			msgid.innerHTML="<div>"+msg+"</div>";
			Effect.Appear(msgid, {queue: {position:"end", scope: msgscope}, duration:0.4});
		}});
	}
	//Else there is no message, so just fade it in
	else
	{
			msgid.innerHTML="<div>"+msg+"</div>";
			Effect.Appear(msgid, {queue: {position:"end", scope: msgscope}, duration:0.4});
	}
}

//Timeout, re-enable the submit button and show a message
function JSFormTimeout(transport)
{
	ChangeMSG(JSForms[2], JSForms[3][3]);
	if($(JSForms[1]).Submit != undefined)
		$(JSForms[1]).Submit.value="Submit";
	$(JSForms[1]).enable();
	JSFormsActive = false;
}

//Given a classname, set the display of everything with that classname to inline
function UnHideLinks(UnhideClass)
{
	var AllHidden = getElementsByStyleClass(UnhideClass);
	
	for(var i=0; i < AllHidden.length; i++)
	{
		AllHidden[i].style.display = "inline";
	}
}

function getElementsByStyleClass (className)
{
  var all = document.all ? document.all :
    document.getElementsByTagName('*');
  var elements = new Array();
  for (var e = 0; e < all.length; e++)
    if (all[e].className == className)
      elements[elements.length] = all[e];
  return elements;
}

//Returns the number of the first option with a matching value, or
//0 if the option is not found
function GetSelectOptNumber(SelectBox, SelectValue)
{
	for(inc=0;inc<SelectBox.options.length;inc++)
	{
		if (SelectBox.options[inc].value.toLowerCase() == SelectValue.toLowerCase())
			return inc;
	}

	return 0;
}

//Selects the first option in the select box given with the value given
function SetSelectByValue(SelectBox, SelectValue)
{
	SelectBox.selectedIndex = GetSelectOptNumber(SelectBox, SelectValue);
}

//Moves the selected items in a given select box up
function SelectMoveUp(element, ChangesVar)
{
	if (ChangesVar == undefined) ChangesMade = true;
	else ChangesVar = true;
	
	for(i = 0; i < element.options.length; i++)
	{
		if(element.options[i].selected == true)
		{
			if(i != 0)
			{
				var temp = new Option(element.options[i-1].text,element.options[i-1].value);
				var temp2 = new Option(element.options[i].text,element.options[i].value);
				element.options[i-1] = temp2;
				element.options[i-1].selected = true;
				element.options[i] = temp;
			}
		}
	}
}

//Moves the selected items in a given select box down
function SelectMoveDown(element, ChangesVar)
{
	if (ChangesVar == undefined) ChangesMade = true;
	else ChangesVar = true;

	for(i = (element.options.length - 1); i >= 0; i--)
	{
		if(element.options[i].selected == true)
		{
			if(i != (element.options.length - 1))
			{
				var temp = new Option(element.options[i+1].text,element.options[i+1].value);
				var temp2 = new Option(element.options[i].text,element.options[i].value);
				element.options[i+1] = temp2;
				element.options[i+1].selected = true;
				element.options[i] = temp;
			}
		}
	}
}

//Adds an item to a select box
function SelectAddItem(SelectBoxID, ItemDisplay, ItemValue, ChangesVar)
{
         if (ChangesVar == undefined) ChangesMade = true;
		 else ChangesVar = true;

         for(inc = 0; inc < SelectBoxID.options.length; inc++)
         {
                 if (SelectBoxID.options[inc].value.toLowerCase() == ItemValue.toLowerCase())
                 {
                    ChangeMSG('MainMSGBar', 'Cannot add duplicate types!');
                    return false;
                 }
         }

         SelectBoxID.options.length++;
         SelectBoxID.options[SelectBoxID.options.length-1].text = ItemDisplay;
         SelectBoxID.options[SelectBoxID.options.length-1].value = ItemValue;
         return true;
}

//Deletes an item from a select box
function SelectDeleteItem(element, ChangesVar)
{
	  if (ChangesVar == undefined) ChangesMade = true;
	  else ChangesVar = true;

	  for(i = (element.options.length - 1); i >= 0; i--)
	  {
		    if(element.options[i].selected == true) 
		    {
		        element.remove(i);
		    }
	  }
}