/** 
  *  Support for all javascript extensions.
  *  @author Ivars Veksins
  */


// -- GARBAGE COLLECTOR -- 

/** 
  * Implementation of garbage collector. Collects DOM 
  * references and releases it on before unload. 
  * 
  * @author Ivars Veksins (ivarsv@gmail.com) 
  */
  
function Garbage() 
{ 
}

/** 
  * Initialise garbage collections of data to be destroyed 
  */
Garbage.init = function() 
{
	if (!window._OBJECTS_)  {
		
		// create storage array 
		window._OBJECTS_ = []; 
		window._FUNCTIONS_ = []; 
		window._EVENTS_ = []; 
		window._CLASSES_ = []; 
	}
}

/** 
  * Called before unload. Goes through all reference 
  * arrays and releases DOM elements. 
  */
Garbage.release = function() 
{
	if (!window._OBJECTS_) 
		return false; 
	
	// release events first. 
	Garbage.release_events(); 
	
	// release objects 
	for (var index in window._OBJECTS_) {
		var element = window._OBJECTS_[index]; 
		
		if (typeof element == "function") 
			continue; 
		
		window._OBJECTS_[index] = null; 
	}
	
	window._OBJECTS_ = null; 
	
	// delete all functions as well 
	for (var index in window._FUNCTIONS_) { 
		var funct = window._FUNCTIONS_[index]; 
		
		funct = null; 
	} 
	
	window._FUNCTIONS_ = null
	
	// call unload 
	for (var index in window._CLASSES_) {
		var cls = window._CLASSES_[index]; 

		if (cls.dispose)
			cls.dispose(); 
			
		window._CLASSES_[index] = null; 
	}
	
	window._CLASSES_ = null; 
	
	return true; 
}

/** 
  * Detaches all events installed using event_install 
  * function. 
  */
Garbage.release_events = function () 
{
	var events = window._EVENTS_; 

	for (var i = 0; i < events.length; i++) { 
		var event = events[i]; 

		detach_event(event[0],event[1],event[2]); 
	}
	
	window._EVENTS_ = null; 
}

/** 
  * Picks up an event to be released on before unload 
  * @argument DOM element event has to be attached to 
  * @argument name of the event i.e. onclick etc.. 
  * @argumetn f function to action on event 
  */
Garbage.push_event = function(obj, event, f) 
{ 
	// init storage arrays 
	Garbage.init(); 

	var length = window._EVENTS_.length; 
	window._EVENTS_[length] = [obj,event,f]; 
}

/** 
  * Collect garbage information about a single object 
  * specified in arguments. 
  */
Garbage.collect = function(obj) {
	
	// initialise garbage 
	Garbage.init(); 
	
	var func = this; 
	
	// populate objects array 
	var object_id = obj._OBJID; 
	if (!object_id) {
		// object id is the last item in the objects array 
		object_id = obj_OBJID = window._OBJECTS_.length;
		window._OBJECTS_ [object_id] = obj; 
	}
	
	// do the same stuff for functions 
	var funct_id = func._FUNCID; 
	if (!funct_id) {
		funct_id = func._FUNCID = window._FUNCTIONS_.length; 
		window._FUNCTIONS_[funct_id] = obj._FUNCT = func; 
	}

	if (!obj._CLOSURES) 	
		obj._CLOSURES = []; 
	
	var closure = obj._CLOSURES[funct_id]; 
	if (closure) 
		return closure; 
		
	// release 
	obj = func = null; 
	
	// Create the closure, store in cache and return result.
	return window._OBJECTS_[object_id]._CLOSURES[funct_id] = function() {
		// page unloaded 
		if (!window._FUNCTIONS_) 
			return; 
			
		return window._FUNCTIONS_[funct_id].apply(window._OBJECTS_[object_id], arguments);
	};	
}


// assign closure function to garbage collector
Function.prototype.garbage = Garbage.collect;	

/** 
  * Function for attaching events to a
  * DOM element. 
  */
function event_install(obj,event_name,f){

	if (obj.addEventListener){	//W3C
		obj.addEventListener(event_name.substr(2), f.garbage(obj),false);
	}else if (obj.attachEvent){	 //IE 
		obj.attachEvent(event_name,f.garbage(obj));
	}
	
	Garbage.push_event(obj, event_name, f); 
}

/** 
  * Detach event from the DOM object 
  */
function detach_event(obj,event_name, f){

	if (obj.removeEventListener) { 
		obj.removeEventListener(event_name.substr(2), f,false);
	} else if (obj.detachEvent) { 
		obj.detachEvent(event_name, f.garbage(obj)); 

	}
}

/** 
  * Extension to custom classes which will implement dispose 
  * method. This allows classes clean their data from memory before page is unloaded
  * 
  * Note that calls will be static 
  * 
  * @argument name of the class
  */
function IMPLEMENT_GARBAGE(f) {
	Garbage.init(); 
	window._CLASSES_[ window._CLASSES_.length ] = f; 
}

event_install(window,"onunload",Garbage.release); 

/***********************************************
* Bookmark site script- © Dynamic Drive DHTML code library (www.dynamicdrive.com)
* This notice MUST stay intact for legal use
* Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code
***********************************************/

/* Modified to support Opera */
function BookmarkSite(title,url){
if (window.sidebar) // firefox
	window.sidebar.addPanel(title, url, "");
else if(window.opera && window.print){ // opera
	var elem = document.createElement('a');
	elem.setAttribute('href',url);
	elem.setAttribute('title',title);
	elem.setAttribute('rel','sidebar');
	elem.click();
} 
else if(document.all)// ie
	window.external.AddFavorite(url, title);
}

function PrintPage()
{
	if( window.print )
	{
		window.print();
	}
	else
	{
		alert( "Mac: Tryck Command + P för att skriva ut sidan\n\nÖvriga: Tryck Ctrl + P för att skriva ut sidan" )
	}
}




function AddHandler( element, eventName, handler )
{
	if (!element)
	{
		alert("Cannot add event handler for: \"" + eventName + "\" - element is undefined or null");
		return;
	}
	if (element.addEventListener)
	{
		element.addEventListener(eventName, handler, false);
	}
	else if (element.attachEvent)
	{
		element.attachEvent("on" + eventName, handler);
	}
	else
	{
		alert("Cannot add event handler for: \"" + eventName + "\" - element does not support addEventListener or attachEvent");
		return;
	}
}
	
function CancelEvent(e)
{
	e = e ? e : window.event;
	if( e.stopPropagation )
		e.stopPropagation();
	if( e.preventDefault )
		e.preventDefault();
		e.cancelBubble = true;
	e.cancel = true;
	e.returnValue = false;
	return false;
}

var searchUrl = "";
var searchTextFieldId = "";

function SearchButton( e )
{
	CancelEvent( e );
	dxDoSearch( searchUrl, searchTextFieldId );
}

function SearchKeyDown( e )
{
	if ( event.keyCode == 13 )
	{
		document.getElementById( searchButtonId ).click();
		CancelEvent( e );
	}
}
