// Functions for use with the GLS Avenue system
// 2005/01/18

function findObject(name) {
  // find an object by name or id
  var obj = document[name];
  var i;
  if (!obj && document.all) {
    obj=document.all[name];
  }
  for (i=0; !obj && i<document.forms.length; i++) {
    obj=document.forms[i][name];
  }
  if (!obj && document.layers) {
    for(i=0; !obj && i<document.layers.length;i++) {
      obj=document.layers[i].document[name];
    }
  }
  if (!obj && document.getElementById) {
    obj=document.getElementById(name);
  }
  return obj;
}

function dump_props(obj) {
  // debug routine: dump properties of object. Probably IE only
  var result = "";
  for (var i in obj) {
    if (String(obj[i]).length <= 30) {
      result += i + " = " + obj[i] + "\n";
    }
  }
  return result;
}

// Functions to check for missing form fields

function isEmpty(inputObj) {
  if (typeof(inputObj)=='string') {
    var el=findObject(inputObj);
    if (!el) {
      window.alert(inputObj);
    }
    inputObj = el;
  }
  // return true if field is empty
  switch(typeof(inputObj.type)=='undefined'?'':inputObj.type) {
    case "text":
    case "textarea":
    case "hidden":
    case "file":
    case "password":
      return (inputObj.value == "");
    case "select-one":
      // If nothing is selected, counts as empty
      if (inputObj.selectedIndex < 0) {
        return true;
      }
      // If selected object has value != "", counts as nonempty.
      // Unfortunately, if optObj.value="", on IE6 this mayindicate that
      // the option has either no value attribute or an empty value
      // attribute, with no way to distinguish between the two,
      // so this only works one way
      var optObj = inputObj.options[inputObj.selectedIndex];
      if (typeof(optObj.value)!="undefined") {
        if (optObj.value) {
          return false;
        }
      }
      // If a visibly empty option was selected, counts as empty
      if (optObj.text=="") {
        return true;
      }
      // If the first element was selected, and it has text but no
      // (or an empty) value attribute, counts as empty
      if (inputObj.selectedIndex == 0) {
        return true;
      }
      return false;
    case "select-multiple":
      return (inputObj.selectedIndex < 0);
    case "checkbox":
    case "radio":
      return (! inputObj.checked);
    default:
      if (typeof(inputObj.length)=='undefined') {
        return false;
      }
      // radiobutton group, or multiple fields with the same name
      for(var i=0; i<inputObj.length; i++) {
        if (typeof(inputObj[i])=='object') {
          if (! isEmpty(inputObj[i])) {
            return false;
          }
        }
      }
      return true;
  }
}

function checkRequired(frm, fields, i0) {
  // This function is given a list of fieldnames or fieldname specifications
  // For all fieldnames specified, it checks whether the named form field
  // has nonempty contents. It returns a list of titles (or names if no
  // title is available) of all empty fields, for reporting to the user.
  // Notes:
  // - Groups of fields with the same name are treated as one, and count as
  //   nonempty if any one of them is nonempty.
  // - In a fieldname specification, the strings '[any]' and '[all]' stand
  //   for arbitrary bracket-enclosed hash indexes. In the first case,
  //   only a single field matching the fieldname specification is required
  //   to be nonempty, in the latter case all such fields are.
  var i, j, k, inputName, el;
  var missing = new Array();
  // Group all form fields by name
  var elementsByName = new Object;
  for (k=0; k<frm.elements.length; k++) {
    el = frm.elements[k];
    if (!elementsByName[el.name]) {
      elementsByName[el.name] = new Array;
    }
    elementsByName[el.name][elementsByName[el.name].length] = el;
  }
  for(i=i0; i<fields.length; i++) {
    var inputName0 = fields[i];
    // Collect all fieldnames matching inputName0
    var inputNames = new Array();
    var checkAll = false;
    if (elementsByName[inputName0]) {
      inputNames[0] = inputName0;
    } else if (inputName0.match(/\[(all|any)\]/)) {
      // The field does not exist as such, but the inputName0 specified
      // is a pattern rather than a literal name
      checkAll = inputName0.match(/\[all\]/);
      var inputNamePattern = new RegExp('^'
          +inputName0.replace(/([\\^$*+?.{}()|\[\]])/g, '\\$1')
          .replace(/\\\[(all|any)\\\]/gi, '\\[[^\\[\\]]*\\]')+'$');
      var useDefaultChecked = false;
      var inputNameDefault;
      for (inputName in elementsByName) {
        if (inputName.match(inputNamePattern)) {
          if (inputName.match(/\[default\]/)) {
            // This is a default input field, only relevant if some
            // other input field has its useDefault checkbox checked
            inputNameDefault = inputName;
            continue;
          }
          if (inputName.match(/\[variantContents\]/)) {
            useDefaultCheckbox = frm[
                inputName.replace(/\[variantContents\]/, '[useDefault]')];
            if (useDefaultCheckbox) {
              if (useDefaultCheckbox.checked) {
                // This input field has its useDefault checkbox checked
                useDefaultChecked = true;
                continue;
              }
            }
          }
          inputNames[inputNames.length] = inputName;
        }
      }
      if (useDefaultChecked && inputNameDefault) {
        // Add the default input field because some other
        // input field has its useDefault checkbox checked
        inputNames[inputNames.length] = inputNameDefault;
      }
    }

    if (inputNames.length==0) {
      window.alert("Checking for nonexisting field '" + inputName0  + "'\n"
          + "(programming error?)");
    } else {
      // Check any/all form fields for nonempty contents
      for(j=0; j<inputNames.length; j++) {
        inputName = inputNames[j];
        var els = elementsByName[inputName];
        for(k=0; k<els.length; k++) {
          if (!isEmpty(els[k])) {
            break;
          }
        }
        if (k<els.length) {
          // At least one input field with this name is nonempty
          if (checkAll) {
            continue; // check others matching this inputName0
          } else {
            break; // we are done with this inputName0
          }
        }
        if (checkAll || j==inputNames.length-1) {
          el = els[0];
          var inputLongName;
          // Report a nonempty form field
          if (typeof(el.title)!='undefined' && el.title.match(/\S/)) {
            inputLongName = el.title;
          } else if (el.length && el[0] && typeof(el[0].title)!='undefined'
              && el[0].title.match(/\S/)) {
            inputLongName = el[0].title;
          } else if (checkAll) {
            inputLongName = inputName
                .replace(/\[variantContents\].*/, '')
                .replace(/\[\]/, '');
          } else {
            inputLongName = inputName
                .replace(/Variants\[.*\]\[variantContents\].*/, '')
                .replace(/\[\]/, '');
          }
          // push() doesn't work in Mac/IE
          missing[missing.length]=inputLongName;
        }
      }
    }
  }
  return missing;
}

function checkForm() {
  // This routine performs all actions necessary before submitting a form,
  // including tranferring all contentEditable DIV's to HIDDEN form inputs
  // and checking for required fields.
  // Syntax: checkForm(formvar, 'requiredField1', 'requiredField2', ...)
  // The form parameter usually gets value 'this', and can be omitted if
  // the form in question is named 'editform'.

  var frm;
  var i0=0;
  if (typeof(arguments[0]) != "object") {
    frm = document.forms["editform"];
  } else {
    frm = arguments[0];
    i0 = 1;
  }
  if (window.storeEditableRegions && window.storeEditableRegions != null) {
    // Store contenteditable DIV's if code for this has been loaded
    // from admin.js
    storeEditableRegions(frm);
  }
  var missing = checkRequired(frm, arguments, i0);
  if (missing.length>0) {
    if (missing.length>1) {
      if (typeof(langNoValuesEnteredWarning)  == 'undefined') {
        langNoValuesEnteredWarning =
            'You didn\'t enter any values for the following fields';
      }
      window.alert(langNoValuesEnteredWarning + ': ' + missing.join(", "));
    } else {
      if (typeof(langNoValueEnteredWarning)  == 'undefined') {
        langNoValueEnteredWarning = 
            'You didn\'t enter a value for the field';
      }
      window.alert(langNoValueEnteredWarning + ': ' + missing[0]);
    }
    return false;
  }
  return true;
}

// Functions to guard against leaving an unsubmitted form by clicking on a link

var formChanged;

function registerChange() {
  // register a change in a form input value
  formChanged = true;
}

function registerReset() {
  // reset change registrations
  formChanged = false;
}


function checkForUnsavedChanges() {
  // Check whether a form contains unsaved changes (inputs that have been 
  // changed), before f.i. following a link to another page
  if (formChanged) {
    if (typeof(langDiscardChangesWarning) == 'undefined') {
      langDiscardChangesWarning = 
        'Changes have not yet been commited. Discard changes?';
    }
    return confirm(langDiscardChangesWarning);
  } else {
    return true;
  }
}

function confirmDeleteAndCheck() {
  // Check whether the current form contains unsaved instructions, AS WELL AS
  // whether the user really indended to activate a link to a delete action
  if (formChanged) {
    if (typeof(langDiscardChangesWarning) == 'undefined') {
      langDiscardChangesWarning = 
        'Changes have not yet been commited. Discard changes?';
    }
    if (! confirm(langDiscardChangesWarning)) {
      return false;
    }
  }

  if (typeof(langDeleteWarning) == 'undefined') {
    langDeleteWarning = 'Are you sure you wish to delete this item?';
  }
  return(confirm(langDeleteWarning));
}

// Functions to manipulate TEXTAREA's

function addTagsToTextArea(el, startTag, endTag) {
  // reset focus from button to textarea field:
  // important for IE fetch-selection mechanism
  el.focus();
  var selectedText, selectStart, selectEnd, selectionRange;
  if (document.selection && document.selection.createRange) {
    // IE: use document.selection
    selectionRange = document.selection.createRange();
    selectedText = selectionRange.text;
  } else if (typeof(el.selectionEnd)!='undefined') {
    // Mozilla: use el.selectionStart & el.selectionEnd
    selectedText = el.value.substring(el.selectionStart, el.selectionEnd);
  } else {
    // other browser: append tags to end of textarea and quit
    el.value = el.value + startTag + endTag;
    return;
  }
  if (! startTag) {
    // insert end tag and move to position after end tag
    selectedText = selectedText + endTag;
    selectStart = selectEnd = selectedText.length;
  } else if (! selectedText) {
    // insert start and end tag and move to position in between
    selectedText = startTag + selectedText + endTag;
    selectStart = selectEnd = startTag.length;
  } else if (startTag==selectedText.substring(0, startTag.length)
      && endTag==selectedText.substring(selectedText.length-endTag.length)) {
    // remove start and end tags and reselect resulting contents
    selectedText = selectedText.substring(
        startTag.length, selectedText.length-endTag.length);
    selectStart = 0;
    selectEnd = selectedText.length;
  } else {
    // add start and end tags and reselect resulting contents
    selectedText = startTag + selectedText + endTag;
    selectStart = 0;
    selectEnd = selectedText.length;
  }
  if (document.selection && document.selection.createRange) {
    // IE: use document.selection
    selectionRange = document.selection.createRange();
    selectionRange.text = selectedText;
    selectionRange.collapse(false);
    selectionRange.moveStart('character', selectStart-selectedText.length);
    selectionRange.moveEnd('character', selectEnd-selectedText.length);
    selectionRange.select();
  } else {
    // Mozilla: use el.selectionStart & el.selectionEnd
    var selectionStart = el.selectionStart;
    var preText = el.value.substring(0, selectionStart);
    var postText = el.value.substring(el.selectionEnd);
    el.value = preText + selectedText + postText;
    el.selectionStart = selectionStart + selectStart;
    el.selectionEnd = selectionStart + selectEnd;
  }
}

function doBBCode(tag, isSmiley) {
// implement phpMyAdmin's BBCode buttons (sort of)
  if (typeof(bbCodeField)=='undefined') {
    if (document.selection) {
      var selectionRange = document.selection.createRange();
      if (selectionRange && selectionRange.parentElement
          && selectionRange.parentElement.tagName == 'TEXTAREA') {
        bbCodeField = selectionRange.parentElement;
      }
    }
  }
  if (typeof(bbCodeField)=='undefined') {
    els = document.getElementsByTagName('TEXTAREA');
    if (els.length==0) {
      return;
    }
    bbCodeField = els[0];
  }
  if (typeof(isSmiley)!='undefined' && isSmiley) {
    addTagsToTextArea(bbCodeField, '', tag);
  } else {
    addTagsToTextArea(bbCodeField, '['+tag+']', '[/'+tag+']');
  }
}

function setBBCodeField(el) {
// Note active textarea field for later use with BBCode buttons
  bbCodeField = el;
}


// Functions for preloading all images given as arguments
// The template engine has created a call to this function for
// all images with a 'preloadSrc=xxx' attribute
var preloadedImages2 = new Array();
var preloadedSrcs2 = new Array();
function preloadImages2() {
  if (arguments.length>0 && document.images) {
    for(var i=0; i<arguments.length; i++) {
      if (arguments[i]) {
        var j = preloadedSrcs2.length;
        preloadedSrcs2[j] = arguments[i];
      }
    }
    window.setTimeout('preloadImages2b()', 200); // Timing sort-of 'body onLoad'
  }
}

function preloadImages2b() {
  if (preloadedSrcs2.length>preloadedImages2.length) {
    for(var i =preloadedImages2.length; i<preloadedSrcs2.length; i++) {
      preloadedImages2[i] = new Image;
      preloadedImages2[i].src = preloadedSrcs2[i];
    }
  }
}

// Function for handling parted fields

function showPart(fieldname, newPartId) {
  // Display a different part of a parted field
  var partIdElement = findObject(fieldname+'PartId');
  if (partIdElement) {
    var oldPartId = parseInt(partIdElement.innerHTML);
    var oldPart = findObject(fieldname+'Part'+oldPartId);
    var newPart = findObject(fieldname+'Part'+newPartId);
    if (oldPart && newPart) {
      var oldPart_style = (document.layers)?oldPart:oldPart.style;
      oldPart_style.display = 'none';
      var newPart_style = (document.layers)?newPart:newPart.style;
      newPart_style.display = 'block';
      partIdElement.innerHTML = newPartId;
      var prevPart = findObject(fieldname+'PartPrev');
      if (prevPart) {
        var prevPart_style = (document.layers)?prevPart:prevPart.style;
        prevPart_style.display = (newPartId>1 ? 'inline' : 'none');
      }
      var nextPart = findObject(fieldname+'PartNext');
      if (nextPart) {
        var nextPart_style = (document.layers)?nextPart:nextPart.style;
        var nextnextPart = findObject(fieldname+'Part'+(newPartId+1));
        nextPart_style.display = (nextnextPart ? 'inline' : 'none');
      }
    }
  }
}

function showPartOffset(fieldname, delta) {
  // Display a different part of a parted field, by offset
  var partIdElement = findObject(fieldname+'PartId');
  if (partIdElement) {
    showPart(fieldname, parseInt(partIdElement.innerHTML)+delta);
  }
}

function showPartForAnchor(anchorname) {
  // Display the part of a parted field containing the named anchor
  var els = document.getElementsByName(anchorname);
  for(var i=0; i<els.length; i++) {
    if (els[i].tagName=='A') {
      var el=els[i];
      while(el) {
        if (el.id && el.id.match(/(.*)Part(\d+)/)) {
          showPart(RegExp.$1, parseInt(RegExp.$2));
        }
        el=el.parentNode;
      }
    }
  }
}         

// Function for mouseovers of buttons
function setButton(btnName, image) {
  var btn = findObject(btnName);
  if (btn != null) {
    if (btn.src) {
      btn.src = wwwroot+'/images/'+image;
    } else {
      btn.className = image.replace(/.*\/|\.[^\/]*$/, '');
    }
  }
}

// Functions to set/get cookies
function getCookie(name) {
  if (!name || !document.cookie) {
    return null;
  }
  var start = document.cookie.indexOf('; '+name+'=');
  if (start!=-1) {
    start+=name.length+3;
  } else {
    start=document.cookie(indexOf(name+'='));
    if (start==0) {
      start=name.length+1;
    } else {
      return null;
    }
  }
  var end = document.cookie.indexOf(';',start);
  if (end == -1) {
    end = document.cookie.length;
  }
  return unescape(document.cookie.substring(len,end));
}

function setCookie(name,value,expires,path,domain,secure) {
  var cookieString = name + "=" + escape(value)
      + ((expires) ? ";expires=" + expires.toGMTString() : "")
      + ((path) ? ";path=" + path : "")
      + ((domain) ? ";domain=" + domain : "")
      + ((secure) ? ";secure" : "");
  document.cookie = cookieString;
}

