// 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);
	    });
    }
  },
  
  _handleAjaxCreate: function(request, xhr){
    var ajaxId = document.body.id;
    if(!ajaxId){ return; }
    request.options.requestHeaders = { 'X-Jcms-Ajax-Id': ajaxId }; // ToDo: Do not override but merge ? 
  },
  
  _205Sync: false,
  _handleAjax205: function(request, xhr){ 
    if (205 != request.transport.status || JcmsJsContext._205Sync){ return; }
    JcmsJsContext._205Sync = true;
    alert(I18N.glp('warn.json.sessiontimeout.205'));
    document.location = document.location;
  },
  
  isIE:  Prototype.Browser.IE,
  isNN4: document.layers ? true : false,
  isNN7: (document.all && document.getElementById) ? true : false,
  isOPERA: Prototype.Browser.Opera,
  isWebKit: Prototype.Browser.WebKit,
  isIE8: document.body.className.indexOf('browser-IE8') >= 0,
  isIE7: document.body.className.indexOf('browser-IE7') >= 0,
  isIE6: document.body.className.indexOf('browser-IE6') >= 0,
  isFirefox: document.body.className.indexOf('browser-Firefox') >= 0
}



// Register
Ajax.Responders.register({ 
  onCreate:   JcmsJsContext._handleAjaxCreate, 
  onComplete: JcmsJsContext._handleAjax205
});


// ---------------------------------------
// 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;
  }
}

// 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){
  JCMS.window.Modal.prompt(msg , func, defvalue);
}

/**
 * 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.
 * @deprecated use isntead JCMS.window.Modal
 */
function confirmAction(msg, url) {
  confirmJSAction(msg, function(){ 
    document.location = url; 
  });
}

/**
 * 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.
 * @deprecated use isntead JCMS.window.Modal
 */
function confirmNoAction(msg, url) {
  JCMS.window.Modal.confirm(msg , function(confirm){ 
    if (confirm){ return; } 
    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.
 * @deprecated use isntead JCMS.window.Modal
 */
function confirmJSAction(msg, func) {
  JCMS.window.Modal.confirm(msg , function(confirm){ 
    if (!confirm){ return; } 
    func();
  });
}

/**
 * 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 ||||||||||||||||||||
// ---------------------------------------

'JCMS.Caddy'.namespace({
  
  displayPopin: function(event, elm) {
    JcmsLogger.info('Caddy', 'displayPopin', elm);

    // Remove previous one if any
    JCMS.Caddy._destroyPopin();

    // Create and show new
    JCMS.Caddy.popinWin = JCMS.Caddy._createPopin(elm);
    JCMS.Caddy.popinWin.open(event);
    
    // Planify autoremoval in 5 seconds
    JCMS.Caddy._autoRemovalTimeout = setTimeout(JCMS.Caddy._destroyPopin, 5000);
    
    Event.stop(event);
  },

  _createPopin: function(elm, options) {
    
    var href = elm.href;
    var url = href + ((href.indexOf('?') == -1) ? '?rd=' : '&rd=') + Math.random();

    var params = {
      elmIds : []
    };
    $$('.caddyUpdate').each(function(elm, idx) {
      var elmId = elm.identify();
      params.elmIds.push(elmId);
      
      var elmParams = elm.readAttribute('rev').toQueryParams(); // use 'rev' attribute, as specified in CaddyTag
      for (var paramName in elmParams) {
        params[elmId + paramName] = elmParams[paramName];
      }
    });
    
    var w = new Control.Window(url, Object.extend({  
        width: 350,
        position: [
          function() { return 20; },
          function() { return document.viewport.getHeight() - (20 + w.container.getHeight()); }
        ],
        parameters : params,
        className: 'caddyPopinWindow',
        method: 'post', // use 'post' and not 'get' to fix bug JCMS-2136
        onComplete : function() {
          params.elmIds.each(function(elmId) {
            var replacedElm = $(elmId);
            var replacementElm = $(elmId + 'Replacement').firstDescendant();
            replacedElm.replace(replacementElm);
            replacementElm.id = replacedElm.id;
          });
          document.fire('caddy:updated');
        }
      }, options || {}));
    
    return w;  
  },
  
  _destroyPopin: function(event) {
    if (!JCMS.Caddy.popinWin) {
      return;
    }
    if (JCMS.Caddy._autoRemovalTimeout) {
      clearTimeout(JCMS.Caddy._autoRemovalTimeout);
    }
      
    JCMS.Caddy.popinWin.close(event);
    JCMS.Caddy.popinWin.destroy();
    if (JCMS.Caddy.popinWin.container.parentNode){ // make sure we remove the div container (livepipe only do this if the original link is not in the DOM)
      JCMS.Caddy.popinWin.container.remove(); 
    }
    JCMS.Caddy.popinWin = null;
  },
  
  closePopin: function(event, elm) {
    if (event) {
      Event.stop(event);
    }
    
    JCMS.Caddy._destroyPopin(event);
  }
});

Util.observeClass('caddyPopin', JCMS.Caddy.displayPopin);
Util.observeClass('caddyPopinClose', JCMS.Caddy.closePopin);

// ---------------------------------------
// ThumbnailTag Functions ||||||||||||||||
// ---------------------------------------

'JCMS.Thumbnail'.namespace({

  /** 
   * 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.
   */ 
  load: function(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(){
  
  // Delay for wysiwyg to be setup before (weird)
  //setupAllTabs();
  
  var t0 = new Date().getTime();
  
  // 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);
  }
  
  var t1 = new Date().getTime();
  JcmsLogger.info('Channel', 'Init Channel OnLoad', ' in '+(t1-t0)+' ms');
}

// Initialization hook up
Event.observe(window, 'load', function() { setupAllTabs(); doOnLoad.defer(); });


