// TODO: Should replace all calls to is* and use those available in JcmsJsContext
var isIE = document.all?true:false;
var isNN4 = document.layers?true:false;
var isNN7 = (document.all && document.getElementById)?true:false;
var isOPERA = (navigator.userAgent.indexOf("Opera") != -1 && document.getElementById)?true:false;
var isSafari = (navigator.userAgent.indexOf("Safari") != -1);

// ---------------------------------------
// Jcms Javascript Context
// ---------------------------------------

var JcmsJsContext = {
  _contextPath : null,
  _baseUrl : null,
  _jsonRPC : null,
  
  /**
   * Returns the current context path retrieved from java.
   * Given by JcmsJspContext through "channel.js" script parameters.
   */
  getContextPath: function() { 
    if (!this._contextPath) { this._init(); }
    return this._contextPath;
  },

  /**
   * Returns the current base URL retrieved from java.
   * Retrieved through the html <base> head tag.
   */
  getBaseUrl: function() {
    if (!this._baseUrl) { this._init(); }
    return this._baseUrl;
  },
 
  /**
   * Returns the JSONRpcClient instance to use for AJAX communication.
   */
	getJsonRPC: function() {
    if (!this._jsonRPC) { 
	    this._jsonRPC = new JSONRpcClient(JcmsJsContext.getContextPath() + "/JSON-RPC");
	  }
	  return this._jsonRPC;
	},
  
  //////////////////////////////////////////////////////////////////
  // Private methods
  
  _init: function() {
    // Read baseUrl from <base > tag
    
    if (!this._baseUrl) {
      JcmsJsContext._baseUrl = document.getElementsByTagName('base')[0].href;
	    JcmsLogger.debug('JcmsJsContext', JcmsJsContext._baseUrl);
    }
    // Read contextPath from channel.js params
	  if (!this._contextPath) {
	    $A(document.getElementsByTagName('script')).findAll( function(s) {
	      return (s.src && s.src.indexOf('js/channel.js') != -1)
	    }).each( function(s) {
	      var indexOfJs = s.src.indexOf('js/channel.js');
	      var queryString = s.src.substring(indexOfJs + 'js/channel.js?'.length);
	      var queryParamsMap = queryString.toQueryParams();
	      
	      // Read context path (If contextpath is empty return '' instead of undefined)
	      JcmsJsContext._contextPath = queryParamsMap.contextPath ? queryParamsMap.contextPath : '';
	      JcmsLogger.debug('JcmsJsContext', JcmsJsContext._contextPath);
	    });
    }
  },
  
  isIE:  document.all ? true : false,
  isNN4: document.layers ? true : false,
  isNN7: (document.all && document.getElementById) ? true : false,
  isOPERA: (navigator.userAgent.indexOf("Opera") != -1 && document.getElementById) ? true : false,
  isSafari: (navigator.userAgent.indexOf("Safari") != -1)
}

// ---------------------------------------
// Form Action Functions |||||||||||||||||
// ---------------------------------------

function getFormElementPos(form, name){

  // Get all elements
  elms = form.elements;
 
  // Find out the (first) current element
  for (var i = 0 ; i < elms.length ; i++){
    if (elms[i].name == name){
      return i;
    }
  }
  return -1;
}

function updateOptionMenu(index, tgtOptions, group){
  for (m = tgtOptions.length-1; m > 0; m--) {
    tgtOptions[m]=null
  }
  for (i = 0; i < group[index].length; i++){
    tgtOptions[i]=new Option(group[index][i].text, group[index][i].value)
  }
  tgtOptions[0].selected=true
}

function setField(field, value) {
  if (field != null) {
    field.value = value;
  }
}

function clearField(e1, e2, e3, e4) {
    if (e1 != null) {
      e1.value = "";
      if (e1.selectedIndex)
        e1.selectedIndex = 0;
    }
    if (e2 != null) {
      e2.value = "";
      if (e2.selectedIndex)
        e2.selectedIndex = 0;
    }
    if (e3 != null) {
      e3.value = "";
      if (e3.selectedIndex)
        e3.selectedIndex = 0;
    }
    if (e4 != null) {
      e4.value = "";
      if (e4.selectedIndex)
        e4.selectedIndex = 0;
    }
}

function blankField(e1, e2, e3, e4) {
    if (e1 != null) {
      e1.value = " ";
    }
    if (e2 != null) {
      e2.value = " ";
    }
    if (e3 != null) {
      e3.value = " ";
    }
    if (e4 != null) {
      e4.value = " ";
    }
}


function uncheckElement(form, i1, i2, i3) {
  if (i1 != null && i1 >= 0) {
    form.elements[i1].checked = false;
  }
  if (i2 != null && i2 >= 0) {
    form.elements[i2].checked = false;
  }
  if (i3 != null && i3 >= 0) {
    form.elements[i3].checked = false;
  }
}

function uncheckAll(form, name, checkbox) {
  if (name != null) {
    var elements = form.elements[name];
    for(i = 0; i < elements.length; i++) {
      if (elements[i] != checkbox) {
        elements[i].checked = false;
      }
    }
  }
}

function checkAll(form, name, checkbox) {
  checkAllwithId(form, name, checkbox, null, null);
}

function checkAllwithId(form, name, checkbox, id) {
  _checkAllwithId(form.elements, name, checkbox, id);
}

function checkAllwithParentId(parentId, name, checkbox, id) {
  
  var elms = $$("#"+parentId+" INPUT[type=checkbox]");
  if (elms){
    _checkAllwithId(elms.toArray(), name, checkbox, id);
  }
}

function _checkAllwithId(elms, name, checkbox, id) {
 
  // Find out the (first) current check
  for (var i = 0 ; i < elms.length ; i++){
    if (elms[i].name != name)
      continue;
    
    if (id != null && elms[i].id.indexOf(id) < 0)
      continue;
      
    checkIt = !elms[i].checked;
    break;
  }

  // Check all in the toggle state
  for (var i = 0 ; i < elms.length ; i++){
    if (elms[i].name != name)
      continue;
    if (id != null && elms[i].id.indexOf(id) < 0)
      continue;
    elms[i].checked = checkIt;
  }
  checkbox.checked = checkIt;
}


function selectAll(form, name){
 selectAllwithId(form, name,null);
}

function selectAllwithId(form, name, id) {

  // Get all elements
  elms = form.elements;
 
  // Find out the (first) current value
  for (var i = 0 ; i < elms.length ; i++){
    if (elms[i].name != name)
      continue;
    
    if (id != null && elms[i].id.indexOf(id) < 0)
      continue;
      
    selectIt = elms[i].selectedIndex;
    break;
  }

  // Check all in the toggle state
  for (var i = 0 ; i < elms.length ; i++){
    if (elms[i].name != name)
      continue;
    if (id != null && elms[i].id.indexOf(id) < 0)
      continue;
    elms[i].selectedIndex = selectIt;
  }
}

function getSelectedElements(form,name,sep){
  elms  = form.elements;
  value = "";
  cpt   = 0;
  for (var i = 0 ; i < elms.length ; i++){
    if (elms[i].name != name)
      continue;
    if (! elms[i].checked)
      continue;
      
    if (cpt > 0)
      value += sep;
    
    value += elms[i].value;
    cpt++;
  }
  return value;
}

// DEPRECATED should be removed
function checkAndSubmitForm(form, field1, field2, error1, error2) {
   
  if (field1 && field1.value == ""){
    alert(error1);
    return;
  }
  
  if (field2 && field2.value == ""){
    alert(error2);
    return;
  }
  
  if (form.onsubmit)
    form.onsubmit();
  form.submit();
}

// ---------------------------------------
// Move Form Functions |||||||||||||||||||
// ---------------------------------------

// Move up/down or delete selected option of a list of select
function moveFormOption(form, pos, op, first, last) {
  array = form.elements;

  // Move Up
  if (op == "up") {
    if (pos > first) { 
      tmp = array[pos].selectedIndex;
      array[pos].selectedIndex = array[pos - 1].selectedIndex;
      array[pos - 1].selectedIndex = tmp;
    } else {
      tmp = array[first].selectedIndex;
      for(i = first; i < last; i++) {
        array[i].selectedIndex = array[i + 1].selectedIndex;
      }
      array[last].selectedIndex = tmp;
    }
  } 
  // Move Down
  else if (op == "down") {
    if (pos < last) {
      tmp = array[pos].selectedIndex;
      array[pos].selectedIndex = array[pos + 1].selectedIndex;
      array[pos + 1].selectedIndex = tmp;
    } else {
      tmp = array[last].selectedIndex;
      for(i = last; i >= first; i--) {
        array[i].selectedIndex = array[i - 1].selectedIndex;
      }
      array[first].selectedIndex = tmp;
    }
  }
  // Remove Element
  else if (op == "remove") {
    for(i = pos; i < last; i++) {
      array[i].selectedIndex = array[i + 1].selectedIndex;
    }
    array[last].selectedIndex = 0;

  }
}

// Move up/down or delete value of list of input
function moveFormElement(form, pos, op, first, last) {
  array = form.elements;

  // Move Up
  if (op == "up") {
    if (pos > first) { 
      tmp = array[pos].value;
      array[pos].value = array[pos - 1].value;
      array[pos - 1].value = tmp;
    } else {
      tmp = array[first].value;
      for(i = first; i < last; i++) {
        array[i].value = array[i + 1].value;
      }
      array[last].value = tmp;
    }
  } 
  // Move Down
  else if (op == "down") {
    if (pos < last) {
      tmp = array[pos].value;
      array[pos].value = array[pos + 1].value;
      array[pos + 1].value = tmp;
    } else {
      tmp = array[last].value;
      for(i = last; i >= first; i--) {
        array[i].value = array[i - 1].value;
      }
      array[first].value = tmp;
    }
  }
  // Remove Element
  else if (op == "remove") {
    for(i = pos; i < last; i++) {
      array[i].value = array[i + 1].value;
    }
    array[last].value = "";

  }
}

// Move up/down or delete value of list of couple of input
function move2FormElement(form, pos, op, first, last) {
  array = form.elements;

  // Move Up
  if (op == "up") {
    if (pos > (first + 1)) { 
      tmp = array[pos].value;
      array[pos].value = array[pos - 2].value;
      array[pos - 2].value = tmp;

      tmp = array[pos - 1].value;
      array[pos - 1].value = array[pos - 3].value;
      array[pos - 3].value = tmp;
    } else {
      tmp1 = array[first].value;
      tmp2 = array[first + 1].value;
      for(i = first ; i < last; i++) {
        array[i].value = array[i + 2].value;
      }
      array[last - 1].value = tmp1;
      array[last].value = tmp2;
    }
  } 
  // Move Down
  else if (op == "down") {
    if (pos < last) {
      tmp = array[pos].value;
      array[pos].value = array[pos + 2].value;
      array[pos + 2].value = tmp;

      tmp = array[pos - 1].value;
      array[pos - 1].value = array[pos + 1].value;
      array[pos + 1].value = tmp;
    } else {
      tmp1 = array[last].value;
      tmp2 = array[last - 1].value;
      for(i = last; i >= first; i--) {
        array[i].value = array[i - 2].value;
      }
      array[first + 1].value = tmp1;
      array[first].value = tmp2;
    }
  }
  // Remove Element
  else if (op == "remove") {
    for(i = pos - 1; i < last; i++) {
      array[i].value = array[i + 2].value;
    }
    array[last - 1].value = "";
    array[last].value = "";

  }
}

// ---------------------------------------
// Change URL Functions ||||||||||||||||||
// ---------------------------------------

function getUrlWithUpdatedParam(url,param,value){
  var targeturl = url.toString();
      
  re1 = new RegExp("([^\?]*\\?.*)("+param+"=[^&]*&?)(.*)","i");
  re2 = new RegExp("([^\?]*\\?)(.*)","i");
  re3 = new RegExp("([^\?]*)","i");
  
  if (targeturl.search(re1) != -1){
    if (value)
      targeturl = targeturl.replace(re1,"$1"+param+"="+value+"&$3");
    else
      targeturl = targeturl.replace(re1,"$1"+"$3");
  }
  else if (targeturl.search(re2) != -1){ 
    if (value)
      targeturl = targeturl.replace(re2,"$1"+param+"="+value+"&$2");
    else
      targeturl = targeturl.replace(re2,"$1"+"$2");
  }
  else { 
    if (value)
      targeturl = targeturl.replace(re3,"$1?"+param+"="+value);
    else
      targeturl = targeturl.replace(re3,"$1");
  }
  
  return targeturl;
}

// ---------------------------------------
// Prompt and Confirm Functions ||||||||||
// ---------------------------------------

function popupWindow(url, title, w, h, status, resizable, scrollbars, reuse, winOpener){
  Popup.popupWindow(url, title, w, h, status, resizable, scrollbars, reuse, winOpener);
}

/**
 * This function prompts the given message and provide a text input. 
 * Then, if the user confirms (OK button), it redirect on the given 
 * URL with the input value bound to the given parameter.
 * 
 * @param msg the message to prompt.
 * @param url the url to redirect on.
 * @param param the name of the parameter used to provide the input value
 * @param defvalue the default value of the text input.
 */
function promptAction(msg , url, param, defvalue){
  
  var redirect = function(value){
    top.document.location = getUrlWithUpdatedParam(url, param, value);
  };
  promptJSAction(msg, redirect, defvalue);
}

/**
 * This function prompts the given message and provide a text input. 
 * Then, if the user confirms (OK button), it execute a javascript
 * function.
 * 
 * @param msg the message to prompt.
 * @param func the function to execute.
 * @param defvalue the default value of the text input.
 */
function promptJSAction(msg , func, defvalue){
  value = top.prompt(msg,defvalue);
  if (value == undefined) {
  	return;
  }
  func(value);
}

/**
 * This function prompts the given message and redirect on the given URL if the user confirms (OK button)
 * @param msg the message to prompt.
 * @param url the url to redirect on.
 */
function confirmAction(msg, url) {
  if (top.confirm(msg)) {
    top.document.location = url;
  }
}

/**
 * This function prompts the given message and execute given function if the user confirms (OK button)
 * @param msg the message to prompt.
 * @param func the function to run.
 */
function confirmJSAction(msg, func) {
  if (top.confirm(msg)) {
    func();
  }
}

/**
 * This function prompts the given message and redirect on the given URL if the user does not confirm (Cancel button)
 * @param msg the message to prompt.
 * @param url the url to redirect on.
 */
function confirmNoAction(msg, url) {
  if (!top.confirm(msg)) {
    top.document.location = url;
  }
}

/**
 * This function will not return until (at least)
 * the specified number of milliseconds have passed.
 * It does a busy-wait loop.
 */
function pause(numberMillis) {
    var now = new Date();
    var exitTime = now.getTime() + numberMillis;
    while (true) {
        now = new Date();
        if (now.getTime() > exitTime)
            return;
    }
}

// ---------------------------------------
// Caddy Functions ||||||||||||||||||||
// ---------------------------------------

/**
 * Swap the current source of the given image with the given second source
 * and second description.
 * Make sure image are correctly loaded to prevent a bug in IE
 * where the image could disapear when swapping.
 */
function swapImgSrcAndDescription(ahref, secondSrc, secondDescription,swapLinkText) {
  
  // Retrieve IMG
  var ahref = $(ahref);
  var img   = ahref.childNodes[0];
  var text  = ahref.childNodes[1];
  
  // Lazy backup of parameters
  if (!img.secondSrc) {
    img.secondSrc   = secondSrc;
    img.secondTitle = secondDescription+".";
    img.secondAlt   = secondDescription;
	  // preload second image
	  if (document.images) {
	    var secondImgPreload = new Image();
	    secondImgPreload.src = img.secondSrc; 
	  }
  }
  
  // Swap Values
  var oldSrc     = img.src;
  var oldTitle   = img.title;
  var oldAlt     = img.alt;
  img.src         = img.secondSrc;
  img.title       = img.secondTitle;
  img.alt         = img.secondAlt;
  img.secondSrc   = oldSrc;
  img.secondTitle = oldTitle;
  img.secondAlt   = oldAlt;
  
  if (swapLinkText && text){
    text.nodeValue = img.alt;
  }
}

// ---------------------------------------
// ThumbnailTag Functions ||||||||||||||||
// ---------------------------------------

/** 
 * Method used by Thumbnail tag to delay thumbnail creation using AJAX call.
 * Calls the Java static method ThumbnailTag.createThumbnailFromSessionAttribute(String)
 * which will look inside the session for the given attribute name in order to
 * create the thumbnail using the params stored in session.
 */ 
function thumbnailTagAjaxLoading(sessionAttrName) {
  try {
    JcmsJsContext.getJsonRPC().ThumbnailTag.createThumbnailFromSessionAttribute( 
    // Anonymous callback called when the Ajax JSONRPC
    // call has been treated on the serverside
    // @param result the result returned by static method
    //        ThumbnailTag.createThumbnailFromSessionAttribute(), that is,
    //        the new thumbnail path, or null if thumbnail creation failed
		function (result, exception) {
		  if (exception) {
		    //alert(exception.message);
		    return;
		  }
      if (result) {
	      var img = $(sessionAttrName);
	      img.hide();
	      img.src = result;
	      Effect.Appear(img, { duration: 0.500 });
      }
		},
    sessionAttrName);
  } catch(ex) { }
}


// ---------------------------------------
// On Load Functions |||||||||||||||||||||
// ---------------------------------------


function doOnLoad(){
  // Text area resizer must be called before tabpane to make
  // sure the textarea are still visible and therefore their
  // width can be retrieved.
  initTextAreaResizer();
  setupAllTabs();
  // popup resizing must occurs after layout (of tabs) has been done
  var popupEditionDiv = $('popupEdition');
  // A test popupEditionDiv.id == 'popupEdition' is added because of a bug in prototype
  // dollar that returns under IE 6.0 and 7.0 the element with name 'popupEdition' instead
  // of a missing element with ID 'popupEdition'  
  if (popupEditionDiv && popupEditionDiv.id == 'popupEdition') {
    Popup.autoResize(popupEditionDiv);
  }
}

// Initialization hook up
Event.observe(window, 'load', function() { setTimeout(doOnLoad,5); });
