/* ======================================================================================================
  Event shortcuts
====================================================================================================== */
function Evt(evt) 
{
  evt = evt ? evt : window.event; 
	this.evt = evt; 
	this.source = evt.target ? evt.target : evt.srcElement;
	this.x = evt.pageX ? evt.pageX : evt.clientX;
	this.y = evt.pageY ? evt.pageY : evt.clientY;
	this.button = marvin.isNetscape ? evt.button + 1 : evt.button;
	
	//this.docX = this.x + document.body.scrollLeft - document.body.clientLeft;
	//this.docY = this.y + document.body.scrollTop  - document.body.clientTop;
	//alert("ST:" + document.body.scrollTop);
	//alert("CT:"+document.body.clientTop);
}

Evt.prototype.toString = function () 
{
	return "Evt [ x = " + this.x + ", y = " + this.y + " ]";
};

Evt.prototype.consume = function () 
{
	if (this.evt.stopPropagation) 
	{
		this.evt.stopPropagation();
		this.evt.preventDefault();
	} 
	else if (this.evt.cancelBubble) 
	{
		this.evt.cancelBubble = true;
		this.evt.returnValue  = false;
	}
};

Evt.addEventListener = function (target,type,func,bubbles) 
{
	if (document.addEventListener) 
	{
		target.addEventListener(type,func,bubbles);
	} 
	else if (document.attachEvent) 
	{
		target.attachEvent("on"+type,func,bubbles);
	} 
	else 
	{
		target["on"+type] = func;
	}
};

Evt.removeEventListener = function (target,type,func,bubbles) 
{
	if (document.removeEventListener) 
	{
		target.removeEventListener(type,func,bubbles);
	} 
	else if (document.detachEvent) 
	{
		target.detachEvent("on"+type,func,bubbles);
	} 
	else 
	{
		target["on"+type] = null;
	}
};



/* ======================================================================================================
  Basic stuff
====================================================================================================== */
  // Use object as a namespace for various functions and variables
var marvin = {};

marvin.key_escape = 27;
marvin.key_enter = 13;
marvin.key_up = 38;
marvin.key_down = 40;
marvin.key_left = 37;
marvin.key_right = 39;
marvin.key_tab = 9;
marvin.key_shift = 16;
marvin.key_ctrl = 17;
marvin.key_backspace = 8;
marvin.key_delete = 46;

marvin.button_left = 1;
marvin.button_right = 2;

marvin.isNetscape = (navigator.appName == "Netscape");

marvin.isIE8 = function()
{
  var agent = navigator.userAgent;

  if (agent.indexOf("MSIE 8.0") != -1 && agent.indexOf("MSIE 9.0") != -1)
    return true;
  else
    return false;

}

marvin.isIE7 = function()
{
  var agent = navigator.userAgent;
  
  if (agent.indexOf("MSIE 7.0") != -1)
    return true;
  else
    return false;
  
}

marvin.isIE6 = function()
{
  var agent = navigator.userAgent;
  
  if (agent.indexOf("MSIE 6.0") != -1)
    return true;
  else
    return false;
  
}

marvin.isFF2 = function()
{
  var agent = navigator.userAgent;
  
  if (agent.indexOf("Firefox/2.0") != -1)
    return true;
  else
    return false;
  
}

marvin.addEvent = function (obj, evType, fn)
{ 
  if (obj.addEventListener)
  { 
    obj.addEventListener(evType, fn, false); 
    return true; 
  } 
  else if (obj.attachEvent)
  { 
    var r = obj.attachEvent("on"+evType, fn); 
    return r; 
  } 
  else 
  { 
   return false; 
  } 
}


marvin.isDeletingChar = function(key)
{
  return key == 8 || key == 46;
}

marvin.alternativeScrollIntoView = function(parentDivId,elementIntoDivId )
{
  var principal = document.getElementById(parentDivId);
  var elementIntoDiv = document.getElementById(elementIntoDivId);

  if (!principal.getClientRects)
  {
    var currentScrollTop = document.documentElement.scrollTop;
    var currentScrollLeft = document.documentElement.scrollLeft;
    elementIntoDiv.scrollIntoView(false);
    document.documentElement.scrollTop = currentScrollTop;
    document.documentElement.scrollLeft = currentScrollLeft;
    return;
  }

  //principal.scrollTop = 0;
  var rects = principal.getClientRects()[0];
  var topFinal = rects.top;
  var bottomFinal = rects.bottom;
  var bottomActual = elementIntoDiv.getClientRects()[0].bottom;
  var topActual = elementIntoDiv.getClientRects()[0].top;
  
  if (bottomActual == 0)
  {
    return;
  }
  
  while(bottomActual>bottomFinal||topActual<topFinal)
  {
    var direction="down";
    
    if(topActual<topFinal)
    {
      direction="up";
    }
    
    if (principal.doScroll)
      principal.doScroll(direction);
    else
    {
      if (direction == "up")
        principal.scrollTop = principal.scrollTop - 5;
      if (direction == "down")
        principal.scrollTop = principal.scrollTop + 5;
    }
    
    bottomActual=elementIntoDiv.getClientRects()[0].bottom;
    topActual=elementIntoDiv.getClientRects()[0].top;
  }
}

marvin.toggleItemsEditable = function(isEditable, idArray)
{
  var cssClassBefore = isEditable ? 'readonly' : '' ;
  var cssClassNow = isEditable ? '' : ' readonly ' ;

  for(idKey in idArray)
  {
    var idName = idArray[idKey];

    // Firefox requires that readonly is set or removed
    if(isEditable)
      document.getElementById(idName).removeAttribute('readOnly');
    else
      document.getElementById(idName).setAttribute('readOnly', true);
    
    // IE requires only setting the parameter
    document.getElementById(idName).readOnly = !isEditable;
    
    document.getElementById(idName).className = document.getElementById(idName).className.replace(cssClassBefore,cssClassNow); 
  }
}

marvin.focusNextElement = function(element, backwards)
{
  // Direction helper functions
  var i;
  var cond;
  var inc;  
  if(!backwards)
  {
    i = 0;
    cond = function(){return i < element.form.length};
    inc = function(){i++};  
  }
  else
  {
    i = element.form.length -1;
    cond = function(){return i >= 0};
    inc = function(){i--};  
  }  
  
  // Find the next input element that is not disabled and focus it
  for (i; cond(); inc())
  {
    var inputElement = element.form[i];
    if(inputElement == element)
    {
      // Found ourselves, find the input to tab into
      for (inc(); cond(); inc())
      {
        var nextElement = element.form[i];
        if(   !nextElement.disabled 
            && nextElement.type != 'hidden' 
            && nextElement.style.visibility !='hidden' 
            && nextElement.style.display !='none')
        {
          nextElement.focus();
          break;
        }
      }
    }
  }
  
  marvin.autocomplete.tabbing = false;
  marvin.autocomplete.shiftKey = false;
}

marvin.padLeft = function(elementId, paddingChar, totalLength)
{
  var element = document.getElementById(elementId);
  var value = element.value;
  
  if (value.length > 0)
  {
    while (value.length < totalLength)
    {
      value = '0' + value;
    }
  }
  
  element.value = value;
}

marvin.autoInsertCharAtPosition = function(elementId, charToInsert, position, evt, ignoreKeys)
{
  var evt = evt || event;

  var element = document.getElementById(elementId);
  var value = element.value;

  // Might have inserted before and user have deleted som chars but not the charToInsert
  
  for (var i=0; i<value.length; i++)
  {
    var curChar = value.charAt(5);
    
    if (curChar == charToInsert)
      return;
  }

  for (ignoreKey in ignoreKeys)
  {
    if (evt.keyCode == ignoreKey)
      return;
  }

  if (value.length == position && evt.keyCode != marvin.key_backspace)
    value = value + charToInsert;
    
  element.value = value;
}

marvin.toggleItemsChecked = function(checked, idArray)
{
  for(idKey in idArray)
  {
    var idName = idArray[idKey];  
    var obj = document.getElementById(idName);
    if(obj!=null) 
      obj.checked = checked ? 'checked' : '';
  }  
}

/* Gets the rendered style of an element 
   Usage: marvin.getStyle(popupDiv, "width"); */
marvin.getStyle = function(element, strCssRule)
{
	var strValue = "";
	if(document.defaultView && document.defaultView.getComputedStyle){
		strValue = document.defaultView.getComputedStyle(element, "").getPropertyValue(strCssRule);
		
	}
	else if(element.currentStyle){
		strCssRule = strCssRule.replace(/-(w|t|l|r|h)/g, function (strMatch, p1){
			return p1.toUpperCase();
		});
		strValue = element.currentStyle[strCssRule];
	}
	
	return strValue;
}

/* ======================================================================================================
  Handling of checks for "data changed by user".
  Involves code to disable/enable various buttons depending on whether or not the user has changed
  any data in the form.
====================================================================================================== */

  // Indicate whether the data has been changed or not
marvin.dataChanged = false;

  // Registered event handlers for data changed events
marvin.dataChangedHandlers = [];

marvin.registerDataChangedHandler = function(handler, param)
{
  this.dataChangedHandlers[this.dataChangedHandlers.length] = { handler: handler, param: param };
}


  // Event handler that enables/disables the associated button
marvin.buttonDataChangedHandler = function(cmd, buttonId)
{
  var button = document.getElementById(buttonId);
  if (button != null)
  {
    if (cmd == "changed")
      button.disabled = false;
    if (cmd == "reset")
      button.disabled = true;
  }
}


  // Event handler that disables/enables the associated button
marvin.buttonDataChangedInvHandler = function(cmd, buttonId)
{
  var button = document.getElementById(buttonId);
  if (button != null)
  {
    if (cmd == "changed")
      button.disabled = true;
    if (cmd == "reset")
      button.disabled = false;
  }
}

// Event handler that resets the content of a FCKEditor
marvin.fckEditorDataChangedHandler = function(cmd, editorInstance)
{
  var editorValue = document.getElementById(editorInstance.Name);
  if (editorValue != null)
  {
    if (cmd == "reset")
    {
      editorInstance.EditorDocument.body.innerHTML = editorValue.value;
      editorInstance.ResetIsDirty();
    }
  }
}

marvin.dataChangedCheckInProgress = false;

  // Base code for calling event handlers when user changes data
marvin.handleDataChanged = function(element)
{
  if (this.dataChangedCheckInProgress)
    return;
  marvin.dataChangedCheckInProgress = true;
  if (element != null)
    marvin.handleMandatoryCheck(element);

  // Check if the user entered text or selected the element (can only check elements which type is known)
  if(( element != null && (element.type == null || element.value != element.defaultValue)) || element == null)    
  {
      // Don't do anything if data is changed already
    if (this.dataChanged == true)
    {
      marvin.dataChangedCheckInProgress = false;
      return;
    }
      
    this.dataChanged = true;
    
    for (var i in this.dataChangedHandlers)
    {
      var handler = this.dataChangedHandlers[i];
      if( handler.handler != null )
        handler.handler("changed", handler.param);
    }
  }
  marvin.dataChangedCheckInProgress = false;
}


marvin.handleMandatoryCheck = function(element)
{
  if ((element.type == "text"  || element.type == "password" || element.tagName == "TEXTAREA") &&  element.className.indexOf("mandatory") >= 0)
  {
    if (element.value == "")
    {
      if (element.className.indexOf(" empty-mandatory") < 0)
      {
        if (element.className.indexOf("mandatory") >= 0)
          element.className = element.className.replace(/[ ]?mandatory/, "");
          
        element.className += " empty-mandatory";
      }
    }
    else
    {
      if (element.className.indexOf("empty-mandatory") >= 0)
        element.className = element.className.replace(/[ ]?empty-mandatory/, "");
        
      if (element.className.indexOf(" mandatory") < 0)
        element.className += " mandatory";
    }
  }
}


  // Base code for calling event handlers when user resets data
marvin.handleDataReset = function()
{
  this.dataChanged = false;
  
  for (var i in this.dataChangedHandlers)
  {
    var handler = this.dataChangedHandlers[i];
    if( handler.handler != null )
      handler.handler("reset", handler.param);
  }
}


  // Called when user clicks a "reset" button.
  // Checks for data changed by user - if changed then make sure user confirms click on reset button
marvin.handleOnClickReset = function(msg)
{
  if (this.dataChanged)
  {
    if (!confirm(msg))
      return false;
  
    // Reset is confirmed - now make sure all event listeners gets to know it
    // Unfortunately some event handlers disable the reset button - and this 
    // also disables the reset functionality, thereby rendering the reset useless!
    // So wait until the reset has been performed, and then call the evnt handlers. Yuck!
    setTimeout("marvin.handleDataReset()", 500);
  }
  return true;
}

/* ======================================================================================================
  Various JavaScript utilities
====================================================================================================== */

marvin.getWindowWidth = function()
{
  return marvin.getWindowDimensions()[0];
}

marvin.getWindowHeight = function()
{
  return marvin.getWindowDimensions()[1];
}

marvin.getWindowDimensions = function()
{
  var x,y;
  if (self.innerHeight) // all except Explorer
  {
	  x = self.innerWidth;
	  y = self.innerHeight;
  }
  else if (document.documentElement && document.documentElement.clientHeight)
	  // Explorer 6 Strict Mode
  {
	  x = document.documentElement.clientWidth;
	  y = document.documentElement.clientHeight;
  }
  else if (document.body) // other Explorers
  {
	  x = document.body.clientWidth;
	  y = document.body.clientHeight;
  }
  
  return [x, y];
}

marvin.getWindowCoords = function(width, height)
{
  var screenW = 800, screenH = 600;

  if (screen.availWidth  &&  screen.availHeight)
  {
    screenW = screen.availWidth;
    screenH = screen.availHeight;
  }
  
  var leftPos = (screenW-width)/2;
  var topPos = (screenH-height)/2;
  
  return "top=" + topPos + "px,screenY=" + topPos + "px,left=" + leftPos + "px,screenX=" + leftPos
         + "px,height=" + height + "px,width=" + width +"px";
}


marvin.getWindowCoordsScreenSized = function(screenPercentageW, screenPercentageH)
{
  var screenW = 800, screenH = 600;

  if (screen.availWidth  &&  screen.availHeight)
  {
    screenW = screen.availWidth;
    screenH = screen.availHeight;
  }
  
  var width = screenW * screenPercentageW / 100;
  var height = screenH * screenPercentageH / 100;
  
  return getWindowCoords(width,height);
}


marvin.openWindowInCenter = function(url, windowName, width, height, otherInfo)
{
  if (otherInfo != null  &&  otherInfo[0] != ',')
    otherInfo = ','+otherInfo;
  return window.open(url, windowName, marvin.getWindowCoords(width,height)+",status=1"+otherInfo);
}


marvin.openWindowScreenSized = function(url, windowName, screenPercentageW, screenPercentageH, otherInfo)
{
  if (otherInfo != null  &&  otherInfo[0] != ',')
    otherInfo = ','+otherInfo;
  return window.open(url, windowName, marvin.getWindowCoordsScreenSized(screenPercentageW,screenPercentageH)+",status=1"+otherInfo);
}

marvin.closePopupWindow = function(popup, testRun)
{
  if (testRun == "False")
  {
    popup.close();
  }
}

// getPageSize()
// Returns array with page width, height and window width, height
// Core code from - quirksmode.org
// Edit for Firefox by pHaez
//
marvin.getPageSize = function()
{
	
	var xScroll, yScroll;
	
	if (window.innerHeight && window.scrollMaxY) {	
		xScroll = document.body.scrollWidth;
		yScroll = window.innerHeight + window.scrollMaxY;
	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}
	
	var windowWidth, windowHeight;
	if (self.innerHeight) {	// all except Explorer
		windowWidth = self.innerWidth;
		windowHeight = self.innerHeight;
	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
	} else if (document.body) { // other Explorers
		windowWidth = document.body.clientWidth;
		windowHeight = document.body.clientHeight;
	}	
	
	// for small pages with total height less then height of the viewport
	if(yScroll < windowHeight){
		pageHeight = windowHeight;
	} else { 
		pageHeight = yScroll;
	}

	// for small pages with total width less then width of the viewport
	if(xScroll < windowWidth){	
		pageWidth = windowWidth;
	} else {
		pageWidth = xScroll;
	}

	arrayPageSize = 
	{
	  pageWidth: pageWidth,
	  pageHeight: pageHeight,
	  windowWidth: windowWidth,
	  windowHeight: windowHeight
	}; 
	return arrayPageSize;
}

marvin.disableActivateButton = false;


marvin.ActivateButton = function(buttonId, evt) {
  var btn = document.getElementById(buttonId);
  if (typeof btn != "undefined") {
    var submit = false;
    if (document.all && evt.keyCode == 13)
      submit = true;
    else if (evt.which == 13)
      submit = true;
      
    if (submit) {
      evt.returnValue = false;
      evt.cancel = true;
      evt.cancelBubble = true;

      if (evt.preventDefault)
        evt.preventDefault();
      
      if(evt.stopPropagation)
        evt.stopPropagation();
    
      
      // Make it possible for other event handlers to (one-shot) disable this feature
      if (marvin.disableActivateButton) {
        marvin.disableActivateButton = false;
      }
      else {
        marvin.disableActivateButton = false;
        var t = evt.target ? evt.target : evt.srcElement;
        t.blur();
        btn.click();
      }
    }
  }
}

marvin.NotEnterPressed = function(evt)
{
  if ( evt.keyCode == 13 )
  {
    return false;
  }
  else
  {
    return true;
  }
}

marvin.NotEnterOrTabPressed = function(evt)
{
  if ( evt.keyCode == 13 )
    return false;
    
  if ( evt.keyCode == 9 )
  {
    marvin.autocomplete.tabbing = true;
    marvin.autocomplete.shiftKey = evt.shiftKey;
    
    return false;
  }

  return true;
}

marvin.getElementsByClass = function(searchClass,node,tag) {
	var classElements = new Array();
	if ( node == null )
		node = document;
	if ( tag == null )
		tag = '*';
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	//var pattern = new RegExp("(^|.*\s|\s)"+searchClass+"(\s|\s.*|$)");
	var pattern = new RegExp('/b^|' + searchClass + '|$/b');
	//var pattern = new RegExp("/"+searchClass+"/");
	for (i = 0, j = 0; i < elsLen; i++) {
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}

marvin.getCursorPosition = function(e) {
  e = e || window.event;
  var cursor = {x:0, y:0};
  if (e.pageX || e.pageY) {
      cursor.x = e.pageX;
      cursor.y = e.pageY;
  } 
  else {
      var de = document.documentElement;
      var b = document.body;
      cursor.x = e.clientX + 
          (de.scrollLeft || b.scrollLeft) - (de.clientLeft || 0);
      cursor.y = e.clientY + 
          (de.scrollTop || b.scrollTop) - (de.clientTop || 0);
  }
  return cursor;
}


/* ======================================================================================================
  Utilities for searching
====================================================================================================== */

marvin.openSearchWindow = function(func, destinationId, query)
{
  marvin.openWindowInCenter("search.aspx?searchtype=field&func="+func+"&destinationId="+destinationId+"&"+query,
                            "", 600, 600, "resizable=1,scrollbars=1");
}


marvin.searchCancel = function()
{
  window.opener.focus();
  window.close();
}

/* ======================================================================================================
  Div toggleling helpers
====================================================================================================== */

marvin.div = {};

marvin.div.show = function(id,displayStyle)
{
  var div = document.getElementById(id);
  if(displayStyle!=null && displayStyle!='')
    div.style.display = displayStyle;
  else
    div.style.display = 'block';
}

/*
marvin.div.showDropDown = function(id, speed, maxheight)
{
  var div = document.getElementById(id);
  if ( div.style.height < maxheight )
    div.style.height = div.style.height + 
}
*/

marvin.div.hide = function(id)
{
  var div = document.getElementById(id);
  div.style.display = 'none';
}

marvin.div.toggle = function(id,displayStyle)
{
  var div = document.getElementById(id);
  
  if ( div.style.display == 'none' )
    marvin.div.show(id,displayStyle);
  else
    marvin.div.hide(id);
}
/* ======================================================================================================
  IMG toggleling helpers
====================================================================================================== */

marvin.img = {};
marvin.img.toggle = function(imgId,imgurlOpen,imgurlClose)
{
  if(document.getElementById(imgId).src == imgurlClose)
    document.getElementById(imgId).src = imgurlOpen;
  else
    document.getElementById(imgId).src = imgurlClose;
}

/* ======================================================================================================
  Popup helpers
====================================================================================================== */

marvin.popup = {};

marvin.popup.findPosition = function ( oLink ) 
{
  var startLink = oLink;
  var posX;
  var posY;
  
  if( oLink.offsetParent ) {
    for( posX = 0, posY = 0; oLink.offsetParent; oLink = oLink.offsetParent ) {
      posX += oLink.offsetLeft;
      posY += oLink.offsetTop;
    }
    
    oLink = startLink;
    
    while (oLink.parentNode && oLink.parentNode.tagName != "BODY")
    {
      oLink = oLink.parentNode;
      
      if (oLink.scrollLeft)
        posX -= oLink.scrollLeft;
      
      if (oLink.scrollTop)
        posY -= oLink.scrollTop;
    }
    
    return [posX, posY];
  } 
  else{
    return [oLink.x, oLink.y];
  }
}

marvin.findMousePosX = function (evt)
{
  if (evt.pageX)
    return evt.pageX;
  else if (evt.clientX)
   return evt.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
  else
    return null;
}

marvin.findMousePosY = function(evt)
{
  if (evt.pageY)
    return evt.pageY;
  else if (evt.clientY)
    return evt.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
  else
    return null;
}

marvin.popup.showAtMouse = function(popupDiv, evt, offsetX, offsetY)
{
  var posX = marvin.findMousePosX(evt);
  var posY = marvin.findMousePosY(evt);

/*  
  var agt = navigator.userAgent.toLowerCase();
  var is_ie = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));
  if ( is_ie )
    offsetY = offsetY;
*/
  marvin.popup.showInPosition(popupDiv, posX, posY, offsetX, offsetY);
}

marvin.popup.showInPlace = function(popupDiv, parentElement, offsetX, offsetY)
{
  var pos = marvin.popup.findPosition(parentElement);

/*  
  var agt = navigator.userAgent.toLowerCase();
  var is_ie = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));
  if ( is_ie )
    offsetY = offsetY;
*/
  marvin.popup.showInPosition(popupDiv, pos[0], pos[1], offsetX, offsetY);
}
  
marvin.popup.showInPosition = function(popupDiv, x, y, offsetX, offsetY)
{
  popupDiv.style.left = (x + offsetX) + 'px';
  popupDiv.style.top = (y + offsetY) + 'px';
  popupDiv.style.position = 'absolute';
  
  marvin.popup.show(popupDiv);
}

marvin.popup.showId = function(popupDivId)
{
  var div = document.getElementById(popupDivId);
  marvin.popup.show(div);
}

marvin.popup.show = function(popupDiv)
{
  popupDiv.style.visibility = 'visible';
  popupDiv.style.display = 'block';
}


marvin.popup.hideId = function(popupDivId)
{
  var popupDiv = document.getElementById(popupDivId);
  marvin.popup.hide(popupDiv);
}


marvin.popup.hide = function(popupDiv)
{
  popupDiv.style.visibility = 'hidden';
  popupDiv.style.display = 'none';
}


marvin.popup.toggle = function(popupDivId)
{
  var div = document.getElementById(popupDivId);
  
  if (div.style.display == 'none' || div.style.visibility == 'none')
    marvin.popup.show(div);
  else
    marvin.popup.hide(div);
}

marvin.popup.toggleInPlaceId = function(popupDivId, parentElementId, offsetX, offsetY)
{
  var parentElement = document.getElementById(parentElementId);
  var popupDiv = document.getElementById(popupDivId);
  
  if ( popupDiv.style.visibility == 'hidden' )
    marvin.popup.showInPlace(popupDiv, parentElement, offsetX, offsetY);
  else
    marvin.popup.hide(popupDiv);
}

marvin.popup.insertIFrameBackground = function(element)
{
  try
  {
    var globalId = 'backgroundIframe';
    
    var iframe = document.getElementById(globalId);
    if (iframe == null)
      iframe = document.createElement('IFRAME'); 
    
    iframe.id = globalId;

    var bordertop = parseInt(marvin.getStyle(element, "border-top-width").replace('px', ''));
    var borderright = parseInt(marvin.getStyle(element, "border-right-width").replace('px', ''));
    var borderbottom = parseInt(marvin.getStyle(element, "border-left-width").replace('px', ''));
    var borderleft = parseInt(marvin.getStyle(element, "border-left-width").replace('px', ''));
    var paddingtop = parseInt(marvin.getStyle(element, "padding-top").replace('px', ''));
    var paddingright = parseInt(marvin.getStyle(element, "padding-right").replace('px', ''));
    var paddingbottom = parseInt(marvin.getStyle(element, "padding-left").replace('px', ''));
    var paddingleft = parseInt(marvin.getStyle(element, "padding-left").replace('px', ''));
    var width = parseInt(marvin.getStyle(element, "width").replace('px', ''))
    var height = parseInt(marvin.getStyle(element, "height").replace('px', ''))
    
    var iframeWidth = borderleft + paddingleft + width + paddingright + borderright;
    var iframeHeight = bordertop + paddingtop + height + paddingbottom + borderbottom;
    
    iframe.style.width = iframeWidth + 'px';
    iframe.style.height = iframeHeight + 'px';
    iframe.style.position = 'absolute';
    iframe.style.zIndex = marvin.getStyle(element, "zIndex") - 1;
    iframe.style.top = marvin.getStyle(element, "top");
    iframe.style.left = marvin.getStyle(element, "left");

    iframe.src = 'javascript:false;';
    iframe.frameBorder = '0';
    
    document.body.appendChild(iframe);
  }
  catch(everything)
  {
    // Happens f.ex. when styles cannot be read as integers. Especially when style is reported as "auto".
  }
}

marvin.popup.hideIFrameBackground = function()
{
  var iframe = document.getElementById('backgroundIframe');
  if (iframe != null)
    document.body.removeChild(iframe);
}


marvin.popup.modalContainer = null;

marvin.popup.showModal = function(elementId, width, height)
{
  var container = new Element('div');
  var overlay = new Element('div');
  overlay.className = 'overlay';
  overlay.style.position = 'absolute';
  overlay.style.top = '0px';
  overlay.style.left = '0px';
  overlay.style.zIndex = 1000;
  
  var pageSize = document.viewport.getDimensions();
  
	overlay.style.height = pageSize.height + "px";
	overlay.style.width = pageSize.width + "px";
	overlay.style.display = 'block';
  Element.setOpacity(overlay, 0.8);
  
  var element = $(elementId);
  element.style.position = 'absolute';
  element.style.display = 'block';
  element.style.top = ((pageSize.height - height ) / 2) + 'px'
  element.style.left = ((pageSize.width - width) / 2) + 'px';
  element.style.width = width + 'px';
  element.style.zIndex = 1001;
  
  element.originalParentNode = element.parentNode;
  
  container.appendChild(overlay);
  container.appendChild(element);
  document.forms[0].appendChild(container);
  
  container.showingElement = element;
  
  marvin.popup.modalContainer = container;
  
  // TODO: Something with iframe background...I dont have the time.
}

marvin.popup.hideModal = function()
{
  if (marvin.popup.modalContainer != null)
  {
    var container = marvin.popup.modalContainer;
    var element = container.showingElement;
    var originalParentNode = element.originalParentNode;
    originalParentNode.appendChild(element);
    element.style.display = 'none';
    
    Element.remove(container);
  }  
}

/* ======================================================================================================
  Autocomplete
====================================================================================================== */

marvin.autocomplete = {};

// How many lines in auto complete list
marvin.autocomplete.lineCount = 0;

// Current selected line in auto complete list
marvin.autocomplete.selectedLineNo = null;

// Location of the values you can select
marvin.autocomplete.values = [];
marvin.autocomplete.titles = [];
marvin.autocomplete.ids = [];

// Reference to text input with auto complete
marvin.autocomplete.inputElement = null;

marvin.autocomplete.inputTitlesElement = null;

// Reference to suggestion div element (list of options)
marvin.autocomplete.suggestionDiv = null;

marvin.autocomplete.suggestionDivIFrame = null;

marvin.autocomplete.timeoutReference = null;

marvin.autocomplete.previousText = null;

marvin.autocomplete.fetchingText = null;

marvin.autocomplete.tabbing = null;

marvin.autocomplete.lookupInProgress = false;

marvin.autocomplete.firstMouseOver = false;

marvin.autocomplete.defaultSelectFirstItem = true;

marvin.autocomplete.ajax = null;


marvin.autocomplete.typeAhead = function(input, text)
{
  if (input.value != '' && input.value != text)
  {
    if (input.createTextRange || input.setSelectionRange)
    {
      var len = input.value.length; 
      input.value = text; 
      marvin.autocomplete.selectRange(input, len, text.length);
    }
  }
  else 
    input.focus();
}


marvin.autocomplete.selectRange = function(input, start, len)
{
  //use text ranges for Internet Explorer
  if (input.createTextRange) 
  {
    var oRange = input.createTextRange(); 
    oRange.moveStart("character", start); 
    oRange.moveEnd("character", len - input.value.length);      
    oRange.select();
  } 
  //use setSelectionRange() for Mozilla
  else if (input.setSelectionRange) 
  {
    input.setSelectionRange(start, len);
  }     

  //set focus back to the input
  input.focus();
}

marvin.autocomplete.ajax_toggle = function(ajax, inputId, titlesInputId, paramInputId, evt, defaultSelectFirstLine, onUpdateHandler, resetSearch)
{
  var suggestionDiv = document.getElementById("marvinSuggestionDiv");
  if ( suggestionDiv.style.visibility == 'visible' )
  {
    marvin.autocomplete.cancelPopup();
    return false;
  }  
  else return marvin.autocomplete.ajax_update(ajax, inputId, titlesInputId, paramInputId, evt, defaultSelectFirstLine, onUpdateHandler, resetSearch);
    
}

// This is the function to call when requesting an Ajax call.
marvin.autocomplete.ajax_update = function(ajax, inputId, titlesInputId, paramInputId, evt, defaultSelectFirstLine, onUpdateHandler, resetSearch)
{
  marvin.autocomplete.ajax = ajax;
  
  marvin.autocomplete.defaultSelectFirstItem = defaultSelectFirstLine;

  var key = (document.all ? evt.keyCode : evt.which);

  var forceSuggestions = false;
  var element = document.getElementById(inputId);
  
  if(element.disabled)
    return;
  if (marvin.autocomplete.inputElement != null) {
    if (key == marvin.key_up) {
      try {
        this.moveSelectedLineUp();
      }
      catch(everything){}
      return false;
    }
    if (key == marvin.key_down) {
      try {
        this.moveSelectedLineDown();
      }
      catch(everything){}
      return false;
    }
    if (key == marvin.key_enter || key == marvin.key_tab) {
    
      if (marvin.autocomplete.ids[marvin.autocomplete.selectedLineNo] != undefined)      
        marvin.autocomplete.selectItem(marvin.autocomplete.ids[marvin.autocomplete.selectedLineNo]);
      else
        marvin.autocomplete.selectItem();
        
      if ((key == marvin.key_tab) && marvin.autocomplete.tabbing) {
         marvin.focusNextElement(element, (marvin.autocomplete.shiftKey || evt.shiftKey));                     
      }
      return false;
    }    
  } 
  else {
    if (key == marvin.key_down) {
       forceSuggestions = true;
     }
  }
  // Ignore when getting focus via tab
  if (key == marvin.key_tab || key == marvin.key_shift) // shift might be the last key up
  {
    // Only tab to next element if the user tries to tab out (keyup)
    if (marvin.autocomplete.tabbing) {
      marvin.focusNextElement(element, (marvin.autocomplete.shiftKey || evt.shiftKey));                     
    }
    return;
  } 
    
  if (resetSearch) {
    element.value = '';
    forceSuggestions = true;
  }
  if (key == marvin.key_escape) {
    element.value = '';
     // Clear titleid prior to the lookup, so the user must select a value
    if(titlesInputId)
      document.getElementById(titlesInputId).value = '';
    marvin.autocomplete.cancelPopup();
    return false;
  }
  

  // Note: try to avoid modifying element here. This starts of various "onchange" handlers.
  var text = element.value;
  var paramInput = document.getElementById(paramInputId);
  if (paramInput == null) // Params can be missing when input is readonly. So ignore ajax request
    return;
  var parameters = document.getElementById(paramInputId).value;
  
  if (text == marvin.autocomplete.previousText  &&  !forceSuggestions)
    return false;
  
   // Clear titleid prior to the lookup, so the user must select a value
  if (titlesInputId)
    document.getElementById(titlesInputId).value = '';
    
  marvin.autocomplete.previousText = text;
  
  var context = { oldText: text, 
                  inputId: inputId,
                  titlesInputId: titlesInputId, 
                  keyCode: evt.keyCode, 
                  which: evt.which 
                };

  clearTimeout(marvin.autocomplete.timeoutReference);
  
  if (key != marvin.key_enter) {
    var suggestionDivIFrame = document.getElementById("marvinSuggestionDiv_iframe");
    marvin.popup.showInPlace(suggestionDivIFrame, element, 0, 20);

    var suggestionDiv = document.getElementById("marvinSuggestionDiv");
    marvin.popup.showInPlace(suggestionDiv, element, 0, 20);
    
    // Ensuring that the popup is in top of everything else.
    // Assuming zIndex of 5000 to be "highest"
    suggestionDiv.style.zIndex = 5000;
    suggestionDivIFrame.style.zIndex = 4999;
    
    if (marvin.autocomplete.fetchingText == null)
      suggestionDiv.innerHTML = "Henter data...";
    else
      suggestionDiv.innerHTML = marvin.autocomplete.fetchingText;
  }
  
  // Fetch optional onUpdate data and pass it to ajax call
  var updateData = ''; // Ajax framework does not handle null values :-(
  if (onUpdateHandler != null) {
    var updateArgs = { inputId: inputId, titlesInputId: titlesInputId, paramInputId: paramInputId };
    updateData = onUpdateHandler(updateArgs);
  }
  
  var f = function() {
            ajax.AjaxUpdate(text, forceSuggestions, parameters, updateData, marvin.autocomplete.update_callback, context);
          };
  marvin.autocomplete.lookupInProgress = true;
  if (forceSuggestions)
    f();
  else
    marvin.autocomplete.timeoutReference = setTimeout(f, 700); // Delay to avoid calling server on every keystroke
  
  marvin.autocomplete.inputElement = document.getElementById(inputId);
  
  return false;
}


marvin.autocomplete.update_callback = function(response)
{
  //alert("response.value[0]: "+response.value[0]+"\n"+"response.value[1]: "+response.value[1]+"\n"+"response.value[2]: "+response.value[2]+"\n"+"response.value[3]: "+response.value[3]+"\n"+"response.value[4]: "+response.value[4]+"\n"+"response.value[5]: "+response.value[5]+"\n");
  if ( response.error != null )
  {
    alert(response.error);
    return;
  }
  marvin.autocomplete.lookupInProgress = false;
  var text = response.value[0];
  var suggestions = response.value[1];
  var enableTypeAhead = response.value[2];
  var lineCount = response.value[3];
  var values = response.value[4];
  var titles = response.value[5];
  var ids = response.value[6];

  var oldText = response.context.oldText;
  var inputId = response.context.inputId;
  var titlesInputId = response.context.titlesInputId;
  var key = (document.all ? response.context.keyCode : response.context.which);

  var input = document.getElementById(inputId);
  var titlesInput = document.getElementById(titlesInputId);
  var suggestionDiv = document.getElementById("marvinSuggestionDiv");
  var suggestionDivIFrame = document.getElementById("marvinSuggestionDiv_iframe");
  
  suggestionDiv.innerHTML = suggestions;

  if (suggestionDiv.style.width == '')
    suggestionDiv.style.width = input.style.width;
      
  if (suggestionDivIFrame.style.width == '')
    suggestionDivIFrame.style.width = input.style.width;

  marvin.autocomplete.inputElement = input;
  marvin.autocomplete.inputTitlesElement = titlesInput;

  marvin.autocomplete.suggestionDiv = suggestionDiv;
  marvin.autocomplete.suggestionDivIFrame = suggestionDivIFrame;
    
  marvin.disableActivateButton = true;
  
  // Update if: some text is available
  //            and user did not press escape
  //            and user did not change the text while the ajax request was pending
  //            - this happens when typing fast
  if (text != null  && input.value == oldText && marvin.autocomplete.suggestionDiv.style.visibility == 'visible')
  {
    if (!marvin.isDeletingChar(key) && enableTypeAhead)
      marvin.autocomplete.typeAhead(input, text);
    
    if (marvin.autocomplete.defaultSelectFirstItem)  
      marvin.autocomplete.selectedLineNo = 0;
    else
      marvin.autocomplete.selectedLineNo = null;
      
    marvin.autocomplete.lineCount = lineCount;
    marvin.autocomplete.values = values;
    marvin.autocomplete.titles = titles;
    marvin.autocomplete.ids = ids;
    
    if (marvin.autocomplete.defaultSelectFirstItem)
      marvin.autocomplete.highlightSelectedLine(true, 'keyboard');
  }
  else
  {
    suggestionDiv.innerHTML = 'Søgningen gav intet resultat...';
  }
}


marvin.autocomplete.scrolling = false;


marvin.autocomplete.cancelPopup = function()
{
  marvin.autocomplete.lookupInProgress = false;
  marvin.autocomplete.firstMouseOver = false;
  marvin.autocomplete.selectedLineNo = null;
  if ( !marvin.autocomplete.scrolling )
  {
    clearTimeout(marvin.autocomplete.timeoutReference);

    if (marvin.autocomplete.inputElement)
    {
      // Fire onchange event even when changed via javascript
      if (   marvin.autocomplete.inputElement.value != marvin.autocomplete.inputElement.defaultValue
          && marvin.autocomplete.inputElement.onchange != null)
        marvin.autocomplete.inputElement.onchange();

      // Update default value to avoid multiple onchange events
      marvin.autocomplete.inputElement.defaultValue = marvin.autocomplete.inputElement.value;

      marvin.autocomplete.inputElement = null;
      
      var suggestionDiv = document.getElementById("marvinSuggestionDiv");
      suggestionDiv.style.visibility = 'hidden';
      suggestionDiv.style.display = 'none';
      
      var suggestionDivIFrame = document.getElementById("marvinSuggestionDiv_iframe");
      suggestionDivIFrame.style.visibility = 'hidden';
      suggestionDivIFrame.style.display = 'none';
    }
  }
  
  marvin.autocomplete.scrolling = false;
}


marvin.autocomplete.cancelPopupDelayed = function(delay)
{
  marvin.autocomplete.timeoutReference = setTimeout(function() {marvin.autocomplete.cancelPopup();}, delay);
}


marvin.autocomplete.highlightSelectedLine = function(enable, inputtype)
{
  if(this.selectedLineNo !=null)
  {
    var liId = "autocompleteLi_" + this.selectedLineNo;
    var liElement = document.getElementById(liId);
    
    if (enable)
    {
      liElement.className = "selected";
      
      if ( inputtype == 'keyboard' )
      {
        var div = liElement.parentNode.parentNode;
        marvin.alternativeScrollIntoView(div.id, liId);
      }
    }
    else
      liElement.className = "";    
  }
}


marvin.autocomplete.moveSelectedLineUp = function()
{
  if (marvin.autocomplete.selectedLineNo > 0)
  {
    marvin.autocomplete.moveSelectedLine(-1);
  }
}


marvin.autocomplete.moveSelectedLineDown = function()
{ 
  if (marvin.autocomplete.selectedLineNo == null)
  {
    marvin.autocomplete.selectedLineNo = 0;
    marvin.autocomplete.highlightSelectedLine(true, 'keyboard');
  }
  else if (marvin.autocomplete.selectedLineNo < marvin.autocomplete.lineCount-1)
  {
    marvin.autocomplete.moveSelectedLine(1);
  }
}


marvin.autocomplete.moveSelectedLine = function(dir)
{
  marvin.autocomplete.highlightSelectedLine(false, 'keyboard');
  marvin.autocomplete.selectedLineNo += dir;
  marvin.autocomplete.highlightSelectedLine(true, 'keyboard');
}


marvin.autocomplete.lineHover = function(lineNo)
{
  marvin.autocomplete.highlightSelectedLine(false, 'mouse');
  marvin.autocomplete.selectedLineNo = lineNo;
  marvin.autocomplete.highlightSelectedLine(true, 'mouse');
}


marvin.autocomplete.selectItem = function(id)
{
  if (marvin.autocomplete.lookupInProgress || marvin.autocomplete.selectedLineNo == null)
    return;
    
  if (marvin.autocomplete.inputElement != null)
  {
    var value = marvin.autocomplete.values[marvin.autocomplete.selectedLineNo];
    if(value != undefined)
    {
      marvin.autocomplete.inputElement.value = value;
      marvin.autocomplete.previousText = value;
      
      // Clear any text selection
      marvin.autocomplete.selectRange(marvin.autocomplete.inputElement,value.length,value.length);
      //if (marvin.autocomplete.inputElement.onchange != null)
        //marvin.autocomplete.inputElement.onchange();

      if (marvin.autocomplete.inputTitlesElement != null)
      {
        titleValue = marvin.autocomplete.titles[marvin.autocomplete.selectedLineNo];
        marvin.autocomplete.inputTitlesElement.value = titleValue; 
      }
      
      var executeString = 'marvin.autocomplete.doPostback_' + marvin.autocomplete.inputElement.id + '();';
      try { eval(executeString); } catch (everything) {}
    }
    
    marvin.autocomplete.inputElement.focus();
    marvin.autocomplete.cancelPopup();
  }

  if (id != '')
    marvin.autocomplete.ajax.AjaxGetSelectedElementInfo(id, marvin.autocomplete.selectItem_callback);
}

marvin.autocomplete.selectItem_callback = function(response)
{
  if (response.error != null)
  {
    alert(response.error);
    return;
  }


  var body = $(document.body);
  body.fire("autocomplete:itemSelected", { item: eval('(' + response.value + ')') });
}


/* ======================================================================================================
  Roll over effects
====================================================================================================== */
marvin.rollover = {};

marvin.rollover.rollover = function(source, cssClass, enable)
{
  if (enable)
  {
    source.className += " "+cssClass;
  }
  else
  {
    // Remove cssClass - apparently Netscape strips leading whitespace in cssClass, so take that into account
    if (marvin.isNetscape)
      source.className = source.className.replace(cssClass,"");
    else
      source.className = source.className.replace(" "+cssClass,"");
  }
}


/* ======================================================================================================
  ColorSelector
====================================================================================================== */
marvin.colorselector = {};

marvin.colorselector.timeout = null;

marvin.colorselector.selectcolor = function(color, divId, targetId, hiddenId)
{
  var target = document.getElementById(targetId);
  target.style.background = color;
  
  var hiddenInput = document.getElementById(hiddenId);
  hiddenInput.value = color;

  marvin.popup.hideId(divId);
}

marvin.colorselector.hideDivIdTimeout = function(divId, time)
{
  marvin.colorselector.timeout = setTimeout(function() { marvin.popup.hideId(divId); } , time); 
}

marvin.colorselector.cancelTimeOut = function()
{
  clearTimeout(marvin.colorselector.timeout);
}


/* ======================================================================================================
  Tables
====================================================================================================== */
marvin.tables = {};

marvin.tables.scrollRowIntoView = function(tableId, rowIndex)
{
  var table = document.getElementById(tableId);
  var row = table.rows[rowIndex];
  
  // Works fine, but unusable when trying to edit something else
  //row.scrollIntoView();
}


/* ======================================================================================================
  Dragging utilities
====================================================================================================== */
marvin.drag = {};

marvin.drag.disableTextSelection = function()
{
	// Ensure cursor movement with mouse down do not function as "select text".
	
	marvin.tableresize.oldOndrag = document.body.ondrag;
	marvin.tableresize.oldOnselectstart = document.body.onselectstart;
	
	document.body.ondrag = function () { return false; };
	document.body.onselectstart = function () { return false; };
}


marvin.drag.enableTextSelection = function()
{
 	document.body.ondrag = marvin.tableresize.oldOndrag;
 	document.body.onselectstart = marvin.tableresize.oldOnselectstart;
}


/* ======================================================================================================
  Row drag
====================================================================================================== */
marvin.rowdrag = {};

// Called OnLoad of page
// Reduces bandwidth: uses javascript to set properties instead of writing them in HTML.
marvin.rowdrag.setupEventHandlers = function(tableId, toolTip)
{
  var table = document.getElementById(tableId);
  var cells;
  if (table)
  {
    cells = table.getElementsByTagName("td");
  }

  if (cells)
  {
    for (var i=0; i<cells.length; ++i)
    {
      var cell = cells[i];
      if (cell.className.indexOf("lineno") != -1)
      {
        cell.onmouseover = function(evt) { marvin.rollover.rollover(this.parentNode, 'lineno-mouseover', true); }
        cell.onmouseout = function(evt) { marvin.rollover.rollover(this.parentNode, 'lineno-mouseover', false); }
        cell.onmousedown = function(evt) { marvin.rowdrag.dragPress(evt); }
        cell.oncontextmenu = marvin.rowdrag.contextMenu;
        cell.title = toolTip;
      }
      else if (cell.className.indexOf("headlineno") != -1)
      {
        cell.onmouseover = function(evt) { marvin.rollover.rollover(this.parentNode, 'lineno-mouseover', true); }
        cell.onmouseout = function(evt) { marvin.rollover.rollover(this.parentNode, 'lineno-mouseover', false); }
      }
    }
  }
}

marvin.rowdrag.dragPress = function(evt)
{
	evt = new Evt(evt);
	
	if (evt.button != marvin.button_left)
	  return;
	
	marvin.rowdrag.startCell = evt.source;
	marvin.rollover.rollover(evt.source, 'lineno-dragged', true);

  // Fetch table (tr-tbody-table)	and mark it as "in dragging mode"
	var table = evt.source.parentNode.parentNode.parentNode;
	table.className += " lineno-dragged";
	//alert(table.tagName);
	table.style.cursor = "pointer";

  //Evt.addMouseListeners(marvin.rowdrag.dragMove, marvin.rowdrag.dragRelease);
	Evt.addEventListener(document, "mousemove", marvin.rowdrag.dragMove, false);
	Evt.addEventListener(document, "mouseup", marvin.rowdrag.dragRelease, false);
	
	marvin.drag.disableTextSelection();
	
	evt.consume();
}


marvin.rowdrag.dragMove = function(evt) 
{
	var evt = new Evt(evt);

	evt.consume();
}


marvin.rowdrag.dragRelease = function(evt) 
{
	evt = new Evt(evt);

	// Verify we are moving in same table
	var sameTable = marvin.rowdrag.startCell.parentNode.parentNode == evt.source.parentNode.parentNode;
	if (sameTable)
	{
    var startRowIndex = marvin.rowdrag.startCell.parentNode.rowIndex;
    var endRowIndex = evt.source.parentNode.rowIndex;

    if (startRowIndex != endRowIndex  &&  startRowIndex-1 != endRowIndex)
    {  	
      if (evt.source.className.indexOf("lineno") != -1 || evt.source.className.indexOf("headlineno") != -1)
      {
        // Postback the move request  
        marvin.rowdrag.postbackDragRelease(startRowIndex, endRowIndex);
      }
    }
  }
  
  // Fetch table (tr-tbody-table)	and mark it as "in dragging mode"
	var table = marvin.rowdrag.startCell.parentNode.parentNode.parentNode;
	table.className = table.className.replace(" lineno-dragged", "");
	
	marvin.rollover.rollover(marvin.rowdrag.startCell, 'lineno-dragged', false);
	
  marvin.drag.enableTextSelection();

	Evt.removeEventListener(document, "mousemove", marvin.rowdrag.dragMove, false);
 	Evt.removeEventListener(document, "mouseup", marvin.rowdrag.dragRelease, false);
}


marvin.rowdrag.contextMenu = function(evt)
{
  evt = new Evt(evt);
  
  var contextDiv = document.getElementById('marvinLineNoContextMenu');
  var popupDiv = contextDiv.childNodes[0];
  var backgroundDiv = contextDiv.childNodes[1];
  
  var pos = marvin.popup.findPosition(evt.source);

  marvin.popup.showInPosition(contextDiv, pos[0], pos[1], 10, 10);
  
  marvin.rowdrag.contextCell = evt.source;

  // Avoid being killen by previous mouse-out (do it before next line!)
  clearTimeout(marvin.rowdrag.contextMenuTimeoutReference);

  // Remove menu if unused after some time
  marvin.rowdrag.disableContextMenuDelayed(5000);
  
  evt.consume();  
  return false;
}


marvin.rowdrag.mouseOutContextMenu = function()
{
  marvin.rowdrag.disableContextMenuDelayed(1000);
}


marvin.rowdrag.disableContextMenuDelayed = function(delay)
{
  marvin.rowdrag.contextMenuTimeoutReference 
    = setTimeout( function() { marvin.popup.hideId('marvinLineNoContextMenu') }, delay );
}


marvin.rowdrag.mouseOverContextMenu = function()
{
  clearTimeout(marvin.rowdrag.contextMenuTimeoutReference);
}


marvin.rowdrag.contextMenuPostback = function(postbackFunction, paramId, confirmMessage)
{
  if (confirmMessage != null)
    if (!confirm(confirmMessage))
      return;
      
  var rowIndex = marvin.rowdrag.contextCell.parentNode.rowIndex;
  var paramInput = document.getElementById(paramId);
  paramInput.value = rowIndex;
  
  postbackFunction();
}


/* ======================================================================================================
  Table resize
====================================================================================================== */
marvin.tableresize = {};


marvin.tableresize.dragPress = function(tableId, userSettingName, evt) 
{
	evt = new Evt(evt);

	marvin.tableresize.tableDiv = document.getElementById(tableId);
	marvin.tableresize.tableDivHeight = parseInt(marvin.tableresize.tableDiv.style.height);
	marvin.tableresize.userSettingName = userSettingName;
	marvin.tableresize.dragElement = evt.source;
	
	marvin.tableresize.dragStartPosY = evt.y;
	
	Evt.addEventListener(document, "mousemove", marvin.tableresize.dragMove, false);
	Evt.addEventListener(document, "mouseup", marvin.tableresize.dragRelease, false);
	
	marvin.drag.disableTextSelection();
}


marvin.tableresize.dragMove = function(evt) 
{
	var evt = new Evt(evt);

	var deltaY = (evt.y - marvin.tableresize.dragStartPosY);
	var divHeight = parseInt(marvin.tableresize.tableDiv.style.height);
	var newHeight = divHeight + deltaY;

//var x = document.getElementById('_ctl0_Page__ctl5_MainContentControl__ctl1_lines_text');
//x.value = "Y: " + evt.y + "/" + deltaY;// + "  DH: " + divHeight + "/" + newHeight;	

	if (newHeight > 30  &&  newHeight < 2000)
	{
	  marvin.tableresize.tableDiv.style.height = (marvin.tableresize.tableDivHeight + deltaY)+"px";

  	marvin.tableresize.dragElement.scrollIntoView();
  }
	
	evt.consume();
}


marvin.tableresize.dragRelease = function(evt) 
{
	evt = new Evt(evt);

	Evt.removeEventListener(document, "mousemove", marvin.tableresize.dragMove, false);
 	Evt.removeEventListener(document, "mouseup", marvin.tableresize.dragRelease, false);
  
  marvin.drag.enableTextSelection();
	
	// Use Ajax to store new table height
	var divHeight = parseInt(marvin.tableresize.tableDiv.style.height);
	DataGridBrowser.StoreHeight(marvin.tableresize.userSettingName, divHeight);
}

/* ======================================================================================================
  IFrame resize
====================================================================================================== */
marvin.iframeresize = {};

marvin.iframeresize.dragPress = function(iframeId, userSettingName, evt) 
{
	evt = new Evt(evt);
	marvin.iframeresize.iframe = document.getElementById(iframeId);
	marvin.iframeresize.iframeHeight = parseInt(marvin.iframeresize.iframe.style.height);
	marvin.iframeresize.userSettingName = userSettingName;
	marvin.iframeresize.dragElement = evt.source;
  
	marvin.iframeresize.dragStartPosY = evt.y;
  
	Evt.addEventListener(document, "mousemove", marvin.iframeresize.dragMove, false);
  Evt.addEventListener(document, "mouseup", marvin.iframeresize.dragRelease, false);
  
	marvin.drag.disableTextSelection();
}


marvin.iframeresize.dragMove = function(evt) 
{
	var evt = new Evt(evt);

	if(evt.button == marvin.button_left)
  {
	  var deltaY = (evt.y - marvin.iframeresize.dragStartPosY);
	  
	  var height = parseInt(marvin.iframeresize.iframe.style.height);
	  
	  var newHeight = height + deltaY;
   
	  if (newHeight > 0  &&  newHeight < 2000)
	  {
	    marvin.iframeresize.iframe.style.height = (marvin.iframeresize.iframeHeight + deltaY)+"px";
    }
  	
	  evt.consume();	  
	  return false;
	}
}

marvin.iframeresize.dragRelease = function(evt) 
{

	evt = new Evt(evt);
	
	Evt.removeEventListener(document, "mousemove", marvin.iframeresize.dragMove, false);
 	Evt.removeEventListener(document, "mouseup", marvin.iframeresize.dragRelease, false);
  
  marvin.drag.enableTextSelection();
	
	// Use Ajax to store new iframe height
	var height = parseInt(marvin.iframeresize.iframe.style.height);
	ResizableIFrame.StoreHeight(marvin.iframeresize.userSettingName, height);
}

/* ======================================================================================================
  Table functions
====================================================================================================== */
marvin.infoRow = {};


marvin.infoRow.hide = function(elementId)
{
  var element = document.getElementById(elementId);
  element.style.display = 'none';
}

marvin.infoRow.show = function(elementId)
{
  var element = document.getElementById(elementId);
  element.style.display = 'inline';
}



marvin.infoRow.showInfoRow = function(elementId, tableColumns, dataKey, ajax)
{
  var element = document.getElementById(elementId);
  var row = element.parentNode.parentNode;
  var table = row.parentNode.parentNode;
  var newRowIndex = row.rowIndex + 1;
  var newRow = table.insertRow(newRowIndex);
  var newCell = newRow.insertCell(0);
  newCell.style.padding = '0px';
  newCell.style.margin = '0px';
  newCell.colSpan = tableColumns;
  newCell.innerHTML = '<div id="infoRowDiv' + dataKey + '" class="infoRowDiv">Henter data...</div>'; 
  row.className += (row.className ? ' ' : '') + 'infoRowActive';
  
  ajax.UpdateInfo(dataKey, marvin.infoRow.updateInfo_callback);
}

marvin.infoRow.hideInfoRow = function(elementId)
{
  var element = document.getElementById(elementId);
  var row = element.parentNode.parentNode;
  var table = row.parentNode;
  var rowIndex = row.rowIndex + 1;
  table.deleteRow(rowIndex);
  row.className = row.className.replace(/[ ]?infoRowActive/, '');
}

marvin.infoRow.updateInfo_callback = function(response)
{
  if ( response.error != null )
  {
    alert(response.error);
    return;
  }

  var text = response.value[0];
  var dataKey = response.value[1];
  
  var divElement = document.getElementById("infoRowDiv" + new String(dataKey));
  divElement.innerHTML = text;
}

/* ======================================================================================================
  Data Lookup functions
====================================================================================================== */
marvin.ajaxdatalookup = {};

marvin.ajaxdatalookup.showing = new Array();

marvin.ajaxdatalookup.ToggleVisible = function (clientId, popupid, useScriptaculous, vOffset, hOffset)
{
  if(  marvin.ajaxdatalookup.showing[popupid]!=null &&  marvin.ajaxdatalookup.showing[popupid] )
    marvin.ajaxdatalookup.hideDiv(popupid, useScriptaculous);
  else
    marvin.ajaxdatalookup.SetVisible(clientId, popupid, useScriptaculous, vOffset, hOffset);
} 


marvin.ajaxdatalookup.findPosition = function ( oLink ) 
{
  var startLink = oLink;
  var initialWidth = oLink.offsetWidth;
  var posX;
  var posY;
  
  if( oLink.offsetParent ) {
    for( posX = 0, posY = 0; oLink.offsetParent; oLink = oLink.offsetParent ) {
      posX += oLink.offsetLeft;
      posY += oLink.offsetTop;
    }
    
    oLink = startLink;
    
  
    while (oLink.parentNode && oLink.parentNode.tagName != "BODY")
    {
      oLink = oLink.parentNode;
      
      if (oLink.scrollLeft && oLink.tagName != 'HTML')
        posX -= oLink.scrollLeft;
      
      if (oLink.scrollTop && oLink.tagName != 'HTML')
        posY -= oLink.scrollTop;
    }
    
    return [ posX, posY, posX + initialWidth ];
  } else {
  
    return [ oLink.x, oLink.y, oLink.x + initialWidth];
  }
}

marvin.ajaxdatalookup.SetVisible = function(clientId, popupid, useScriptaculous, vOffset, hOffset, posMode, evt, insertIFrame, zeroPositionElement)
{ 
  var divElement = document.getElementById(popupid);
  var parentElement = document.getElementById(clientId);
  
  // Make sure absolute position is calculated correct
  
  if (zeroPositionElement != null && zeroPositionElement == 'form')
    document.forms[0].appendChild(divElement);
  else
    document.body.appendChild(divElement);
  
  if (!useScriptaculous)
    divElement.style.display = 'block';
    
  divElement.style.position = 'absolute';

  divElement.style.zIndex = 20 + marvin.ajaxdatalookup.calcTop();
  
  var posObject;
  
  if (posMode == null || posMode == 'topright' || posMode == 'topleft')
    posObject = marvin.ajaxdatalookup.findPosition(parentElement);    
  else
    posObject = [marvin.findMousePosX(evt), marvin.findMousePosY(evt), marvin.findMousePosX];

  if (posMode == null || posMode == 'topright')
  {
    divElement.style.top = (posObject[1] + vOffset) + 'px';
    divElement.style.left = (posObject[2] + hOffset) + 'px';
  }
  else
  {
    divElement.style.top = (posObject[1] + vOffset) + 'px';
    divElement.style.left = (posObject[0] + hOffset) + 'px';
  }
  
  marvin.ajaxdatalookup.showing[popupid] = true;  
  if(useScriptaculous)            
      new Effect.Appear(popupid, {duration: 0.5}); 

  if (insertIFrame == null || insertIFrame == true)
    marvin.popup.insertIFrameBackground(divElement);
}

marvin.ajaxdatalookup.calcTop = function ()
{
  var topMod = 0;
  for (val in marvin.ajaxdatalookup.showing )            
  {
    var divElement = document.getElementById(val);
    if(marvin.ajaxdatalookup.showing[val] && divElement != null)
      topMod = divElement.style.zIndex > topMod ? divElement.style.zIndex + 1 : topMod;
  }
  return topMod;
}
          
marvin.ajaxdatalookup.hideDiv = function(popupid, useScriptaculous)
{
  var divElement = document.getElementById(popupid);
  var divElementBack = document.getElementById(popupid + '_popupDivShadow');
  if(useScriptaculous)            
    new Effect.Fade(popupid, {duration: 0.5});
  else
    divElement.style.display = 'none';
  marvin.ajaxdatalookup.showing[popupid] = false;  
  
  marvin.popup.hideIFrameBackground();

} 

marvin.ajaxdatalookup.getContents = function(id, parameterString, ajax)
{      
  ajax.GetContents(id, parameterString, marvin.ajaxdatalookup.getContents_callback);
}


marvin.ajaxdatalookup.getContents_callback = function(response)
{
  if ( response.error != null )
  {
    alert(response.error +"\n" + response.request.responseText);
    return;
  }

  var text = response.value[0];
  var id = response.value[1];
  
  var spanFrame = document.getElementById(new String(id));
  spanFrame.innerHTML = text;
}

/* ======================================================================================================
 Marvin Dragdrop 
====================================================================================================== */
marvin.dragdrop = {};
marvin.dragdrop.dragging;

marvin.dragdrop.param1;
marvin.dragdrop.param2;


marvin.dragdrop.start = function(id, param, hiddenId)
{
  hiddenId.value = param;
  marvin.dragdrop.param1 = param;
  marvin.dragdrop.dragging = true;
  
  marvin.drag.disableTextSelection();
}

marvin.dragdrop.end = function(id, param, hiddenId)
{
    if( marvin.dragdrop.dragging )
    {
      hiddenId.value = param;
      marvin.dragdrop.param2 = param;
      marvin.dragdrop.dragging = false;
      marvin.dragdrop.postbackDragRelease(marvin.dragdrop.param1, marvin.dragdrop.param2);
    }
}

marvin.dragdrop.over = function(id, param)
{
  if( marvin.dragdrop.dragging )
  {
    id.className = " dragdropOver";
  }
}

marvin.dragdrop.out = function(id, param)
{
  if( marvin.dragdrop.dragging )
  {
	  id.className = id.className.replace(" dragdropOver", "");
  }
}

/* ======================================================================================================
 Editable Literal
====================================================================================================== */
marvin.editableLiteral = {};

marvin.editableLiteral.oldOnSubmit;

marvin.editableLiteral.showTextBox = function(textInputID, literalSpanID, editSpanID, saveImageID)
{
  var literalSpan = document.getElementById(literalSpanID);
  var editSpan = document.getElementById(editSpanID);
  var textInput = document.getElementById(textInputID);

  literalSpan.style.display = 'none';
  editSpan.style.display = 'block';
  editSpan.style.whiteSpace = 'nowrap';
  
  var text = literalSpan.innerHTML;
  
  while (text.toLowerCase().indexOf('<br>', 0) != -1)
  {
    text = text.replace('<br>', '\r\n');
    text = text.replace('<BR>', '\r\n');
  }
  
  textInput.value = text;  
  textInput.focus();
  textInput.select();
}


marvin.editableLiteral.handleKeyDown = function(e, saveImageID, textInputID, literalSpanID, editSpanID, ajax, parameterString, type, emptyText)
{
  if (!marvin.NotEnterPressed(e) && type != "textarea")
  {
    marvin.editableLiteral.saveChange(parameterString, textInputID, literalSpanID, editSpanID, ajax, emptyText);
    return false;
  }
  else if (e.keyCode == marvin.key_escape)
  {
    marvin.editableLiteral.cancelEdit(textInputID, literalSpanID, editSpanID);
    return false;
  }
  else
  {
    return true;
  }
}

marvin.editableLiteral.cancelEdit = function(textInputID, literalSpanID, editSpanID)
{
  var literalSpan = document.getElementById(literalSpanID);
  var editSpan = document.getElementById(editSpanID);

  literalSpan.style.display = 'block';
  editSpan.style.display = 'none';
}

marvin.editableLiteral.saveChange = function(parameterString, textInputID, literalSpanID, editSpanID, ajax, emptyText)
{

  var literalSpan = document.getElementById(literalSpanID);
  var editSpan = document.getElementById(editSpanID);
  var textInput = document.getElementById(textInputID);
  
  ajax.SaveChange(textInput.value, literalSpanID, parameterString, emptyText, marvin.editableLiteral.saveChange_callback);
  
  literalSpan.style.display = 'block';
  literalSpan.innerHTML = 'Gemmer...';
  
  editSpan.style.display = 'none';
}

marvin.editableLiteral.saveChange_callback = function(response)
{

  var literalSpan = document.getElementById(response.value[0]);
  var text = response.value[1];
  literalSpan.innerHTML = text;
}

/* ======================================================================================================
 Context Menu
====================================================================================================== */

marvin.contextMenu = {};

//document.onclick = function() {hideContextMenu();}

marvin.contextMenu.KeySelected = null;
marvin.contextMenu.Display = false;

marvin.contextMenu.hideContextMenu = function(contextMenuId)
{
  if (!marvin.contextMenu.Display)
  {
    var contextMenu = document.getElementById(contextMenuId);
    contextMenu.style.display = 'none';
  }
  marvin.contextMenu.Display = false;
}

marvin.contextMenu.showContextMenu = function(contextMenuId, element, key, e, ajax, openOffsetX, openOffsetY)
{
  marvin.contextMenu.Display = true;
  marvin.contextMenu.KeySelected = key;
  
  document.onclick = function() {marvin.contextMenu.hideContextMenu(contextMenuId);}
  
  var contextMenu = document.getElementById(contextMenuId);
  var cursorPos = marvin.getCursorPosition(e);

  // Make sure absolute position is calculated correct
  document.body.appendChild(contextMenu);
    
  contextMenu.style.display = 'block';
  contextMenu.style.position = 'absolute';
  contextMenu.style.left = cursorPos.x + openOffsetX + 'px';
  contextMenu.style.top = cursorPos.y + openOffsetY + 'px';
  
  marvin.contextMenu.doMenuAccessControl(contextMenuId, key, ajax);
}

marvin.contextMenu.handleItemClicked = function(action, commandArgumentId, commandNameId)
{
  var commandArgumentElem = document.getElementById(commandArgumentId);
  var commandNameElem = document.getElementById(commandNameId);
  
  commandArgumentElem.value = marvin.contextMenu.KeySelected;
  commandNameElem.value = action;
 
  handleContextMenuAction();
}

marvin.contextMenu.handleItemClientFunction = function(callFunction)
{
  var commandArgument = marvin.contextMenu.KeySelected;
  
  callFunction = callFunction.replace("$commandArgument$", commandArgument);
  
  eval(callFunction);
}

marvin.contextMenu.doMenuAccessControl = function(contextMenuId, key, ajax)
{
	var menu = document.getElementById(contextMenuId);
	var items = menu.getElementsByTagName('div');
	for (var i=0; i<items.length; i++)
	{
		marvin.contextMenu.doItemAccessControl(items[i].id, key, ajax);
	}
}

marvin.contextMenu.doItemAccessControl = function(itemId, key, ajax)
{
	ajax.HandleAccessControl(itemId, key, marvin.contextMenu.doItemAccessControl_callback);
}

marvin.contextMenu.doItemAccessControl_callback = function(response)
{
	var itemId = response.value[0];
	var result = response.value[1];
	
	if (result)
	  marvin.contextMenu.enableItem(itemId);
	else
		marvin.contextMenu.disableItem(itemId);
}

marvin.contextMenu.enableItem = function(itemId)
{
	try
	{
	  var item = document.getElementById(itemId);
	  item.className = "item";
	  item.onmouseover = function(){ item.className = 'hover'; item.style.cursor = 'pointer'; };
	  item.onmouseout = function(){ item.className = 'item'; item.style.cursor = 'default'; };
	  
	  if (item.originalOnclick)
	    item.onclick = item.originalOnclick;
  }
	catch(everything){} 
}

marvin.contextMenu.disableItem = function(itemId)
{
	try
	{
		var item = document.getElementById(itemId);
		item.className = "item disabled";
		item.onmouseover = function(){ item.style.cursor = 'not-allowed'; };
		item.onmouseout = function(){ item.className = 'item disabled'; item.style.cursor = 'default'; };
		
		if (item.onclick != null)
		  item.originalOnclick = item.onclick;
		  
		item.onclick = null;
  }
	catch(everything){} 
}

/* ======================================================================================================
 StagePlan 
 ======================================================================================================*/
marvin.stagePlan = {};

marvin.stagePlan.todayDiv_ClientID;

marvin.stagePlan.Lines;

marvin.stagePlan.Offset;

marvin.stagePlan.todayDiv_initialize = function()
{
  var todayDiv = document.getElementById(marvin.stagePlan.todayDiv_ClientID);
  
  if (todayDiv)
  {
    // Find initial position
    var parentPos = marvin.popup.findPosition(todayDiv.parentNode);
    var parentPosX = parentPos[0];
    var parentPosY = parentPos[1];
    
    todayDiv.style.top = parentPosY + 'px';
		
    todayDiv.style.height = (marvin.stagePlan.Lines * 22) + 'px';
    
    todayDiv.style.left = (parentPosX + marvin.stagePlan.Offset) + 'px';
  }
}

/* ======================================================================================================
 Scrollable
 ======================================================================================================*/

marvin.scrollable =  {};

marvin.scrollable.sliderDivId = null;
marvin.scrollable.leftImageId = null;
marvin.scrollable.rightImageId = null;
marvin.scrollable.scrollSizeX = null;
marvin.scrollable.minScrollX = null;
marvin.scrollable.maxScrollX = null;
marvin.scrollable.currentScrollX = 0;
marvin.scrollable.ID = null;

marvin.scrollable.initialize = function(minScrollX, maxScrollX, scrollSizeX, leftImageId, rightImageId ,sliderDivId, currentScrollX, ID)
{
  marvin.scrollable.minScrollX = minScrollX;
  marvin.scrollable.maxScrollX = maxScrollX;
  marvin.scrollable.scrollSizeX = scrollSizeX;
  marvin.scrollable.leftImageId = leftImageId;
  marvin.scrollable.rightImageId = rightImageId;
  marvin.scrollable.sliderDivId = sliderDivId;
  marvin.scrollable.currentScrollX = currentScrollX;
  marvin.scrollable.ID = ID;
    
  marvin.scrollable.checkScrollX(minScrollX, maxScrollX);
}

marvin.scrollable.moveBy = function(elementId, yoffset, xoffset)
{
  marvin.scrollable.currentScrollX -= xoffset;
  Effect.MoveBy(elementId, yoffset, xoffset, {afterFinish:function(){marvin.scrollable.handleMoveFinish();}});
}

marvin.scrollable.handleMoveFinish = function()
{
  Scrollable.SaveScroll(marvin.scrollable.currentScrollX, marvin.scrollable.ID);
  marvin.scrollable.checkScrollX();
}

marvin.scrollable.checkScrollX = function()
{
  if (marvin.scrollable.currentScrollX <= marvin.scrollable.minScrollX)
    marvin.scrollable.disableScroll('left');
  else
    marvin.scrollable.enableScroll('left');

  if (marvin.scrollable.currentScrollX >= marvin.scrollable.maxScrollX)
    marvin.scrollable.disableScroll('right');
  else
    marvin.scrollable.enableScroll('right');
}

marvin.scrollable.disableScroll = function(direction)
{
  var dirImage = null;

  if (direction == 'left')
  {
    dirImage = document.getElementById(marvin.scrollable.leftImageId);
  }
  if (direction == 'right')
  {
    dirImage = document.getElementById(marvin.scrollable.rightImageId);
  }

  if (dirImage)
  {
    dirImage.onclick = null;
    dirImage.style.cursor = 'not-allowed';
  }
}

marvin.scrollable.enableScroll = function(direction)
{
  var dirImage = null;

  if (direction == 'left')
  {
    dirImage = document.getElementById(marvin.scrollable.leftImageId);
    dirImage.onclick = function(){marvin.scrollable.moveBy(marvin.scrollable.sliderDivId, 0, marvin.scrollable.scrollSizeX);};
  }
  if (direction == 'right')
  {
    dirImage = document.getElementById(marvin.scrollable.rightImageId);
    dirImage.onclick = function(){marvin.scrollable.moveBy(marvin.scrollable.sliderDivId, 0, -marvin.scrollable.scrollSizeX);};
  }

  if (dirImage)
  {
    dirImage.style.cursor = 'pointer';
  }
}

/* ======================================================================================================
 Collapsible items based on state data
====================================================================================================== */

marvin.collapsible = {};

marvin.collapsible.toggle = function(img, id, serverResult,useScriptaculous)
{
  var value = serverResult.value;
  if(useScriptaculous) Effect.toggle(id,'slide');
  else
  {
    if (value[0]) // isCollapsed?
    {    
      marvin.div.hide(id);
    }
    else
    {
      marvin.div.show(id);
    }
}  
  img.src = value[1];
  img.alt = value[2];
  img.title = value[2];
}

marvin.collapsible.expand = function(collapsibleImgId, collapsiblePanelId)
{
  if ($(collapsiblePanelId).visible())
    return;
  else
    $(collapsibleImgId).onclick();
}

marvin.collapsible.collapse = function(collapsibleImgId, collapsiblePanelId)
{
  if ($(collapsiblePanelId).visible())
    $(collapsibleImgId).onclick();
}


/* ======================================================================================================
 ModalWindowFrame
====================================================================================================== */

marvin.modalwindowframe = {};

marvin.modalwindowframe.overlayDivId = null;

marvin.modalwindowframe.overlayFrameId = null;

marvin.modalwindowframe.initialize = function(overlayDivId, overlayFrameId)
{
  marvin.modalwindowframe.overlayDivId = overlayDivId;
  marvin.modalwindowframe.overlayFrameId = overlayFrameId;
}

marvin.modalwindowframe.showFrame = function()
{
  var overlay = document.getElementById(marvin.modalwindowframe.overlayDivId);
  var pageSize = marvin.getPageSize();
	overlay.style.height = pageSize.windowHeight+"px";
	overlay.style.width = pageSize.windowWidth+"px";
	overlay.style.display = 'block';
}

marvin.modalwindowframe.hideFrame = function()
{
  var overlay = document.getElementById(marvin.modalwindowframe.overlayDivId);
  var frame = document.getElementById(marvin.modalwindowframe.overlayFrameId);
	
	overlay.style.display = 'none';
	form.style.display = 'none';
}

/* ======================================================================================================
 CheckBoxList
====================================================================================================== */

marvin.checkBoxList = {};

marvin.checkBoxList.toggleAllSelected = function(sender, listId)
{
//debugger;
  var checkBoxes = marvin.checkBoxList.getCheckBoxesRecursively(listId);
  for (var i=0; i<checkBoxes.length; i++)
  {
    checkBoxes[i].checked = sender.checked;
  }
}

marvin.checkBoxList.getCheckBoxesRecursively = function(listId)
{
  var checkBoxArray = new Array();
  var element = document.getElementById(listId);
  marvin.checkBoxList.getCheckBoxes(element, checkBoxArray);
  return checkBoxArray;
}

marvin.checkBoxList.getCheckBoxes = function(element, checkBoxArray)
{
  for (var i=0; i<element.childNodes.length; i++)
  {
    var e = element.childNodes[i];

    if (e.tagName)
    {
      if (e.tagName.toLowerCase() == 'input' && e.type.toLowerCase() == 'checkbox')
      {
        checkBoxArray.push(e);
      }
      else
      {
        marvin.checkBoxList.getCheckBoxes(e, checkBoxArray);
      }
    }
    else
    {
      marvin.checkBoxList.getCheckBoxes(e, checkBoxArray);
    }
  }    
}

/* ======================================================================================================
 BookmarkPageLink
====================================================================================================== */
marvin.bookmarkpage = function(url, title)
{
  if ((navigator.appName == "Microsoft Internet Explorer") && (parseInt(navigator.appVersion) >= 4)) 
  {
    window.external.AddFavorite(url,title);
  } 
  else if (navigator.appName == "Netscape") 
  {
    window.sidebar.addPanel(title,url,"");
  } 
  else 
  {
    alert("Press CTRL-D (Netscape) or CTRL-T (Opera) to bookmark");
  }
}

/* ======================================================================================================
Overlayed
====================================================================================================== */

marvin.overlay = {};

marvin.overlay.overlayContainer = null;

marvin.overlay.showOverlayed = function(elementId, width, height)
{
  var overlay = new Element('div');
  overlay.className = 'overlay';
  overlay.style.position = 'absolute';
  overlay.style.top = '0px';
  overlay.style.left = '0px';
  overlay.style.zIndex = 90;

  var pageSize = document.viewport.getDimensions();
  overlay.style.height = pageSize.height + "px";
  overlay.style.width = pageSize.width + "px";
  overlay.style.display = 'block';
  Element.setOpacity(overlay, 0.8);

  var element = $(elementId);
  element.style.display = 'block';
  element.style.position = 'absolute';
  element.style.zIndex = 1000;

  if (height == null)
    height = Element.getHeight(element);

  element.style.top = ((pageSize.height - height) / 2) + 'px';
  element.style.left = ((pageSize.width - width) / 2) + 'px';

  element.style.width = width + 'px';

  element.originalContainer = element.parentNode;

  var container = new Element('div');
  container.className = 'overlay-container';
  container.appendChild(overlay);
  container.appendChild(element);

  container.overlayElement = element;
  marvin.overlay.overlayContainer = container;

  document.forms[0].appendChild(container);

  // Register escape event to hide overlay
  if (marvin.isIE6() || marvin.isIE7())
    marvin.addEvent(document, "keypress", function(evt) { marvin.overlay.handleKeyPressed(evt); });
  else
    marvin.addEvent(window, "keypress", function(evt) { marvin.overlay.handleKeyPressed(evt); });

}

marvin.overlay.hideOverlayed = function()
{
  if (marvin.overlay.overlayContainer != null)
  {
    var container = marvin.overlay.overlayContainer;

    container.overlayElement.style.display = 'none';
    container.overlayElement.originalContainer.appendChild(container.overlayElement);

    Element.remove(container);
  }
}

marvin.overlay.handleKeyPressed = function(e)
{
  var evt = e || event;
  var key = evt.keyCode;

  if (key == 27)
  {
    if (marvin.overlay.overlayContainer != null)
    {
      marvin.overlay.hideOverlayed();
    }
  }
}

