var textIndex = 'text_index';
var pageIndex = 'page_index';
var childrenIndex = 'children_index';
var debug = true;

/* Array to hold all menus in the page */
var menusInPage = new Array;

/* Prefix for naming menus */
var menuName = 'menu_';

/* Prefix for naming menu items */
var menuItemName    = 'menuItem_';

/* Prefix for naming pop up menu divs */
var popUpHolderName = 'popUpHolder_';

/* Prefix for naming menu links */
var menuLinkName    = 'menuLink_';

/* Timer for menu hiding */
var timer;

/* Timeout for menu hiding*/
var timeout = 500;

var currentLeft   = 0;
var currentHeight = 0;
/*
 * Array holding the style parameters for each menu level. 
 * To add a new level, duplicate an enty and alter values accordingly
 */
var menuStyle = 
[
  //Main bar
  { 
    /* Position relative to menu container */
    'topPosition':  0,
    'leftPosition': 0,
    
    /* Z-index */
    'z-index': 0,

    /* CSS styles */
    'divStyle': 'mainMenuItem',
    'aStyle':   'mainMenuLink',

    /* 
     * Offset from one element to the next. Must be changed according to sizing in the CSS file 
     * One of them should be zero, depending on whether the menu is horizontal or vertical, if 
     * both are != 0, the menu will be shown in a nice diagonal.
     */
    'xOffset': 85,
    'yOffset': 0,
    
    /* Events */
    'onMouseOver': mainMenuItemOnMouseOver,
    'onMouseOut':  mainMenuItemOnMouseOut,
    'onClick':     mainMenuItemOnClick
  },
  
  //First level
  { 

    /* Position relative to menu container */
    'topPosition':  0,
    'leftPosition': 0,

    /* CSS styles */
    'containerStyle': 'firstLevelMenuHolder',
    'divStyle':       'firstLevelMenuItem',
    'aStyle':         'firstLevelMenuLink',

    /* 
     * Offset from one element to the next. Must be changed according to sizing in the CSS file 
     * One of them should be zero, depending on whether the menu is horizontal or vertical, if 
     * both are != 0, the menu will be shown in a nice diagonal.
     */
    'yOffset': 30,
    'xOffset': 0,
    
    /* Events */
    'onMouseOver':    firstLevelMenuItemOnMouseOver,
    'onMouseOut':     firstLevelMenuItemOnMouseOut,
    'onClick':        firstLevelMenuItemOnClick,
    'divOnMouseOut':  popUpMenuOnMouseOut,
    'divOnMouseOver': popUpMenuOnMouseOver
  }
];

/**
 * Function:    writeJSMenu
 * Descripcion: writes the JS Menu structure on the page.
 * Parameters:  menuStructure: array containing the structure of the menu
 * Returns:     none
 */
function writeJSMenu( menuStructure ){
  
  //Create the name for this menu
  var thisMenuName = menuName + menusInPage.length;
  
  menusInPage[thisMenuName] = writeJSMenuRecursive( menuStructure, "mainmenu", 0 );
  menusInPage.length++; //Dunno why, adding the menu like I do it doesn't increment the size :?
}

/**
 * Function:    writeJSMenuRecursive
 * Descripcion: writes the JS Menu structure on the page.
 * Parameters:  menuStructure: array containing the structure of the menu
 *              menuHolderID:  ID of the div holding the menu
 *              level:         current level
 * Returns:     none
 */
function writeJSMenuRecursive( menuStructure, menuHolderID, level ){
  
  //Initially, the array holding the level is null. Gets a value if 
  //a menu is created
  var levelArray = null;
  
  //If the var passed is an array
  if( menuStructure instanceof Array ){
    /* Find the div holding the menu */
    var menuHolder = document.getElementById( menuHolderID );
       
    /* Calculate initial offset for centering the elements within the container */
    if( menuStyle[level]['xOffset'] != 0 ) { 
      //If menu is horizontal
      var totalWidth     = menuStructure.length * 
                           parseInt( menuStyle[level]['xOffset'] );
      var containerWidth = parseInt( getElementStyle( menuHolderID, 'width', 'width' ) );

      if( containerWidth != 0 ) {
        menuStyle[level]['leftPosition'] 
                        = Math.floor( ( containerWidth - totalWidth ) / 2 );
      }                
    }  

    if( menuStyle[level]['yOffset'] != 0 ){
      //If menu is vertical 
      var totalHeight     = menuStructure.length * 
                            parseInt( menuStyle[level]['yOffset'] );
      var containerHeight = parseInt( getElementStyle( menuHolderID, 'height', 'height' ) );
      
      if( containerHeight != 0 ){
        menuStyle[level]['topPosition'] 
                 = Math.floor( ( containerHeight - totalHeight ) / 2 );
      }
    }                      

    /* Create the array to hold every item */                        
    levelArray = new Array;
    
    /* Create every item */
    var i = 0;
    for( ; i < menuStructure.length; i++ ){      
      //Create current menu Item
      menuItem = createMenuElement( menuStructure[i], level, i );
      
      //Add it to the corresponding holder
      menuHolder.appendChild( menuItem );

      //Initialize pop up menu 
      var popUpMenuLevel = null;

      //Process children to create pop up menus
      var linkChildren = menuStructure[i][childrenIndex];
    
      //Add item to array
      levelArray[i] = new Array;
      levelArray[i]['menuItemDiv'] = menuItem.id;

      //Create children if needed
      if( linkChildren != null ){
        popUpMenuLevel = createChildren( linkChildren, menuHolder, menuItem, level + 1, i );
      }  
      
      //Add item to array
      levelArray[i]['popUpMenu']   = popUpMenuLevel;
    }
  }
  return levelArray;
}

/**
 * Function:    createChildren
 * Descripcion: creates the div containing a child menu
 * Parameters:  linkChildren: array holding the children items
 *              menuHolder:   div holding the upper menu level
 *              menuItem:     menuItem, parent of the child menu
 *              level:        current level
 * Returns:     returns the new element
 */
function createChildren( linkChildren, menuHolder, menuItem, level, position ){
  //Get values of current item
  var containerTop  = parseInt( getElementStyle( menuHolder.id, 'top', 'top' ) );
  var containerLeft = parseInt( getElementStyle( menuHolder.id, 'left', 'left' ) );
    
  // Calculate position of pop up menu 
  //Initial pos would be 0 if it was relative to the div holding the item 
  //But it has to be set regarding absolute (0,0).
  if( menuStyle[level-1]['xOffset'] != 0 ) { 
    //If menu bar is horizontal
    topPos  = containerTop  + parseInt( getElementStyle( menuHolder.id, 'height', 'height' ) ) - 5;
    leftPos = containerLeft + parseInt( getElementStyle( menuItem.id, 'left', 'left' ) );
  }

  if( menuStyle[level-1]['yOffset'] != 0 ) { 
    //If menu bar is vertical
    topPos  = containerTop  + parseInt( getElementStyle( menuItem.id, 'top', 'top' ) );
    leftPos = containerLeft + parseInt( getElementStyle( menuHolder.id, 'width', 'width' ) ) - 5;
  }                   

  currentHeight = topPos;
  currentLeft = leftPos;
  
  //Create pop up holder
  var popUpHolder = document.createElement( 'div' );  
  popUpHolder.id           = popUpHolderName + (level-1) + '_' + position;
  popUpHolder.className    = menuStyle[level]['containerStyle'];
  popUpHolder.onmouseover  = menuStyle[level]['divOnMouseOver'];
  popUpHolder.onmouseout   = menuStyle[level]['divOnMouseOut'];
  popUpHolder.onclick      = menuStyle[level]['onClick'];      
  popUpHolder.style.top    = topPos + 'px';
  popUpHolder.style.left   = leftPos + 'px';
  popUpHolder.style.visibility = 'hidden';
  
  //No matter how the initial bar is placed, the divs after the main bar are always vertical. 
  //The width is set by css
  popUpHolder.style.height 
              = (linkChildren.length * parseInt( menuStyle[level]['yOffset']) ) + 'px';
  
  //Cannot be appended to the item, as it would be added inside that div...
  document.getElementById( ['maindiv'] ).appendChild( popUpHolder );
  //document.getElementById( popUpHolder.id ).style.visibility = 'false';  

  
  //Write children after having added the menu holder to the page, otherwise it can't be done 
  var elements = writeJSMenuRecursive( linkChildren, popUpHolder.id, level ); 

  //Create the structure holding the menu and return it.  
  var popUpLevel = new Array;
  popUpLevel['popUpMenuDiv'] = popUpHolder.id;
  popUpLevel['elements'] = elements;
  return popUpLevel;
}


/**
 * Function:    createMenuElement
 * Descripcion: creates an item in the menu
 * Parameters:  currentElement: array element holding the info to create the menu item
 *              level:          current level (to retrieve CSS information)
 *              i:              position of the current item in the current level.
 * Returns:     returns the new element
 */
function createMenuElement( currentElement, level, i ){
  
  //Calculate position within container
  var topPos  = menuStyle[level]['topPosition']  
                + ( parseInt( menuStyle[level]['yOffset']) * i );
  var leftPos = menuStyle[level]['leftPosition'] 
                + ( parseInt( menuStyle[level]['xOffset']) * i );
  if( level != 0 ) {
    leftPos += 5;
    topPos  += 5;
  }
  
  //Create div element to hold this menu item
  var menuItem = document.createElement( 'div' );
  menuItem.id          = menuItemName + level + '_' + i;
  menuItem.className   = menuStyle[level]['divStyle'];
  menuItem.onmouseover = menuStyle[level]['onMouseOver'];
  menuItem.onmouseout  = menuStyle[level]['onMouseOut'];
  menuItem.onclick     = menuStyle[level]['onClick'];      
  menuItem.style.top   = topPos + 'px';
  menuItem.style.left  = leftPos + 'px';
   
  //Create link element for this menu item
  var menuItemLink = document.createElement( 'a' );
  menuItemLink.id        = menuLinkName + level + "_" + i;
  menuItemLink.className = menuStyle[level]['aStyle'];
  menuItemLink.href      = currentElement[pageIndex];
  menuItemLink.onmouseover = menuStyle[level]['onMouseOver'];
  menuItemLink.onclick     = menuStyle[level]['onClick'];      
  
  //Create text element within the link
  var menuItemText = document.createTextNode( currentElement[textIndex] ); 
  
  //Create hierachy
  menuItemLink.appendChild( menuItemText );
  menuItem.appendChild( menuItemLink );
  
  return menuItem;
}

/**
 * Function:    getElementStyle
 * Descripcion: reads the style of an element, as the styles set via CSS files 
 *              can't be read directly
 * Parameters:  elementID:    id of the current element
 *              IEStyleProp:  property to be read (IE style, i.e., marginLeft )
 *              CSSStyleProp: property to be read (CSS style, i.e., margin-left );
 * Returns:     returns the value of the property for the given element, 
 *              or an empty string if it's not set.
 */
function getElementStyle ( elementID, IEStyleProp, CSSStyleProp ) {
  var element = document.getElementById( elementID );
  var property = "0";
  if( element.currentStyle ){
    //Internet Explorer
    property = element.currentStyle[IEStyleProp];
  } else {
    HM_IsSafari = ((document.getElementById)&&  (parseInt(navigator.productSub)>=20020000)&&  (navigator.vendor.indexOf("Apple Computer")!=-1));
    if( HM_IsSafari ){
      if( elementID == "maindiv" ){
        if( CSSStyleProp = 'top' ){
          property = 135;
        } else if ( CSSStyleProp = 'left' ){
          property = 230;
        } else if ( CSSStyleProp = 'width' ){
          property = 520;
        } else if ( CSSStyleProp = 'left' ){
          property = 40;
        }
      } else if( elementID.indexOf( menuItemName ) != -1 ){
        if( CSSStyleProp = 'height' ){
          property = currentHeight;
        } else if ( CSSStyleProp = 'left' ){
          property = currentLeft;
        }
      }
    }
    else{
      //Other browsers (Safary does not support getComputedStyle)
      var compStyle = window.getComputedStyle( element, "" );
      property = compStyle.getPropertyValue( CSSStyleProp );
    }
  }
  //alert( "element: " + element.id + ", propety: " + CSSStyleProp + ", value: " + property );
  return property;
}

/**
 * Function:    myAlert
 * Description: Debuggin function. If the global var debug is set to true, it
 *              simply calls the standard alert funcion with the given argument,
 *              if debug is set to false, it does nothing. Nice way to turn
 *              debugging on/off with one var in JS as well :-)
 * Parameters:  The object to be debugged.
 * Returns:     none. 
 */
function myAlert( object ){
  if( debug == true ){
    alert( object );
  }
}

/**
 * Function:    mainMenuItemOnMouseOver
 * Description: Called when the mouse moves over a main menu item.
 * Parameters:  Event that triggered the call.
 * Returns:     none. 
 */
function mainMenuItemOnMouseOver( evt ) {
  //Stupid line needed for IE :?
  evt = ( (evt) ? evt : ( (event) ? event : null ) );
  var targetElement = ( (evt.target) ? evt.target : evt.srcElement );
  showPopUpMenuMainLevel( targetElement.id );
}

/**
 * Function:    mainMenuItemOnMouseOut
 * Description: Called when the mouse moves out of a main menu item.
 * Parameters:  Event that triggered the call.
 * Returns:     none. 
 */
function mainMenuItemOnMouseOut( evt ) {
  //Stupid line needed for IE :?
  evt = ( (evt) ? evt : ( (event) ? event : null ) );
  var targetElement = ( (evt.target) ? evt.target : evt.srcElement );
  timer = setTimeout( "hidePopUpMenuMainLevel( '" + targetElement.id + "' )", timeout );
}

/**
 * Function:    mainMenuItemOnClick
 * Description: Called when a main menu item is clicked.
 * Parameters:  Event that triggered the call.
 * Returns:     none. 
 */
function mainMenuItemOnClick( evt ) {
}


/**
 * Function:    firstLeveMenuItemOnMouseOver
 * Description: Called when the mouse moves over a first level menu item.
 * Parameters:  Event that triggered the call.
 * Returns:     none. 
 */
function firstLevelMenuItemOnMouseOver( evt ) {
  /*
  //Stupid line needed for IE :?
  evt = ( (evt) ? evt : ( (event) ? event : null ) );
  var targetElement = ( (evt.target) ? evt.target : evt.srcElement );
  showPopUpMenu( targetElement.id );
  */
}


/**
 * Function:    firstLeveMenuItemOnMouseOut
 * Description: Called when the mouse moves out of a first level menu item.
 * Parameters:  Event that triggered the call.
 * Returns:     none. 
 */
function firstLevelMenuItemOnMouseOut( evt ) {
  /*
  //Stupid line needed for IE :?
  evt = ( (evt) ? evt : ( (event) ? event : null ) );
  var targetElement = ( (evt.target) ? evt.target : evt.srcElement );
  hidePopUpMenu( targetElement.id );
  */
}


/**
 * Function:    firstLeveMenuItemOnClick
 * Description: Called when a first level menu item is clicked.
 * Parameters:  Event that triggered the call.
 * Returns:     none. 
 */
function firstLevelMenuItemOnClick( evt ) {
}

/**
 * Function:    popUpMenuOnMouseOut
 * Description: Called when the mouse leaves a first level menu div.
 * Parameters:  Event that triggered the call.
 * Returns:     none. 
 */
function popUpMenuOnMouseOut ( evt ){
  //Stupid line needed for IE :?
  evt = ( (evt) ? evt : ( (event) ? event : null ) );
  var targetElement = ( (evt.target) ? evt.target : evt.srcElement );
  timer = setTimeout( "hidePopUpDiv( '" + targetElement.id + "' )", timeout );
}

/**
 * Function:    popUpMenuOnMouseOut
 * Description: Called when the mouse enters a first level menu div.
 * Parameters:  Event that triggered the call.
 * Returns:     none. 
 */
function popUpMenuOnMouseOver( evt ){
  clearTimeout( timer );
  /*
  //Stupid line needed for IE :?
  evt = ( (evt) ? evt : ( (event) ? event : null ) );
  var targetElement = ( (evt.target) ? evt.target : evt.srcElement );
  showPopUpMenu( targetElement.id );
  */
}

/**
 * Function:    showPopUpMenuMainLevel
 * Description: Shows a child menu
 * Parameters:  Id of the parent item of the child menu to be shown.
 * Returns:     none. 
 */
function showPopUpMenuMainLevel( id ){
  clearTimeout( timer );
  var found = false;
  for( k = 0; k < menusInPage.length && !found; k++ ){
    currentMenu = menusInPage[menuName + k];
    for( i = 0; i < currentMenu.length && !found; i++ ){
      currentItem = currentMenu[i];
      var popUpElement = currentItem['popUpMenu'];
      if( popUpElement != null ) {
        //In case the element that triggered the showing is the link instead of the div
        if( id.slice(-4) == currentItem['menuItemDiv'].slice(-4) ){
          //Found the element to show 
          document.getElementById( popUpElement['popUpMenuDiv'] ).style.visibility = 'visible';
          found = true;
        } else { 
          //Hide any other element
          document.getElementById( popUpElement['popUpMenuDiv'] ).style.visibility = 'hidden';
        }
      }
    }
  }
}

/**
 * Function:    hidePopUpMenuMainLevel
 * Description: Hides a child menu
 * Parameters:  Id of the parent item of the child menu to be hidden.
 * Returns:     none. 
 */
function hidePopUpMenuMainLevel( id ){
  var found = false;
  for( k = 0; k < menusInPage.length && !found; k++ ){
    currentMenu = menusInPage[menuName + k];
    for( i = 0; i < currentMenu.length && !found; i++ ){
      currentItem = currentMenu[i];
      //In case the element that triggered the showing is the link instead of the div
      if( id.slice(-4) == currentItem['menuItemDiv'].slice(-4) ){
        //Found the element to show 
        var popUpElement = currentItem['popUpMenu'];
        if( popUpElement != null ) {
          document.getElementById( popUpElement['popUpMenuDiv'] ).style.visibility = 'hidden';
        }
        found = true;
      } 
    }
  }
}

/**
 * Function:    showPopUpMenu
 * Description: Shows a child menu
 * Parameters:  Id of the parent item of the child menu to be shown.
 * Returns:     none. 
 */
function showPopUpMenu( id ){
  clearTimeout( timer );
}

/**
 * Function:    hidePopUpMenu
 * Description: Hides a child menu
 * Parameters:  Id of the parent item of the child menu to be hidden.
 * Returns:     none. 
 */
function hidePopUpMenu( id ){
}

/**
 * Function:    hidePopUpDiv
 * Description: Hides a pop up menu. Called when the mouse leaves the div holding the pop up
 * Parameters:  Id of the div holding the menu to be hidden
 * Returns:     none. 
 */
function hidePopUpDiv( id ){
  if( id.search(/popUp/) != -1 ){
    document.getElementById( id ).style.visibility = 'hidden';  
  }
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * ADMIN FUNCTIONS
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
 * Function:    valueExistsInArray
 * Description: checks in the value entered in the field named inputName exists in the given array
 * Parameters:  stack: array to check
 *              needle: value to check
 * Returns:     true if the value exists in the array
 *              false otherwise. 
 */

function valueExistsInArray( stack, needle ){
  var exists = false;
  
  for( i = 0; i < stack.length && !exists; i++ ){
    if( needle == stack[i] )
    {
      exists = true;
    }
  }
  return exists;
}

/**
 * Function:    addItem
 * Description: Validates the item id entered by the user before submiting the form
 * Parameters:  none
 * Returns:     true if the item id is valid, so that the form is submited,
 *              false otherwise. 
 */
function addItem( items ){
  var doSubmit = addGeneric( items, 'inputMenuItemID' );
  return doSubmit;
}

/**
 * Function:    editItem
 * Description: If the button pressed was "Edit", makes the form fields editable. 
 *              If the button pressed was "Save", simply submits the form.
 * Parameters:  who: id of the line to edit/save
 * Returns:     true if the button pressed was save, so that the form is submited, 
 *              false otherwiser. 
 */
function editItem( who, items ){
  var elements = [
                   'inputMenuItemID', 
                   'inputText', 
                   'inputPosition', 
                   'selectParentItem', 
                   'inputPage',
                   'selectGroup'
                 ];
  var doSubmit = editGeneric( who, items, elements );
  return( doSubmit );
  /*
  var doSubmit = false;
  var what = document.getElementById( 'buttonSave' + who ).value;
  //alert( "what: " + what + " who: " + who );
  if( what == 'Save' ){
    doSubmit = true; //We're saving, that's php business
  } else if ( what == 'Edit' ){ //Editing: enable fields
    document.getElementById( 'inputMenuItemID' + who ).disabled = false;
    document.getElementById( 'inputMenuItemID' + who ).readOnly = true;
    document.getElementById( 'inputText' + who ).disabled = false;
    document.getElementById( 'selectParentItem' + who ).disabled = false;
    document.getElementById( 'inputPage' + who ).disabled = false;
    document.getElementById( 'selectGroup' + who ).disabled = false;
    document.getElementById( 'buttonSave' + who ).value = "Save";
    document.getElementById( "oldPage" ).value = 
             document.getElementById( 'inputPage' + who ).value;
    for( i = 0; i < items.length; i++ ){
      if( items[i] != who && items[i] != 'Root Item'){
        document.getElementById( 'buttonSave' + items[i] ).disabled = true;    
      }
    }
  }
  return( doSubmit );*/
}

/**
 * Function:    deleteItem
 * Description: ask for confirmation before submiting the form.
 * Parameters:  none
 * Returns:     true if the user confirms delete, false otherwise. 
 */
function deleteItem(){
var doSubmit = deleteGeneric( "This will delete the selected item and all of its children" + 
              "\nClick Ok to proceed, Cancel otherwise" );
  return doSubmit;
}

/**
 * Function:    addGeneric
 * Description: Validates the d entered by the user before submiting the form
 * Parameters:  none
 * Returns:     true if the id is valid, so that the form is submited,
 *              false otherwise. 
 */
function addGeneric( existing, id ){
  element = document.getElementById( id )
  doSubmit = !( valueExistsInArray( existing, element.value ) );
  if( !doSubmit ){
    alert( "The code you entered already exists!!!" );
    element.focus();
  }
  return doSubmit;
}

/**
 * Function:    editGeneric
 * Description: processes the generic behaviour when saving an element.
 * Parameters:  who: id of the line to edit/save
 *              buttons: array containing the ids to suffix to the button id, so that
 *                       the buttons can be disabled
 *              elements: array containing th ids of the elements to be enabled
 * Returns:     true if the user confirms delete, false otherwise. 
 */
function editGeneric( who, buttons, elements ){
  var doSubmit = false;
  var button   = document.getElementById( 'buttonSave' + who );
  var what     = button.value;
  if( what == 'Save' ){
    doSubmit = true; //We're saving, that's php business
  } else if ( what == 'Edit' ){ //Editing: enable fields
    document.getElementById ( elements[0] + who ).readOnly = true;
    for( i = 0; i < elements.length; i++ ){
      document.getElementById( elements[i] + who ).disabled = false;
    }
    for( i = 0; i < buttons.length; i++ ){
      if( buttons[i] != who  && buttons[i] != 'Root Item'){
        document.getElementById( 'buttonSave' + buttons[i] ).disabled = true;    
      }
    }
    button.value = "Save";
   }
  return( doSubmit );
}

/**
 * Function:    deleteGeneric
 * Description: ask for confirmation before deleting
 * Parameters:  none
 * Returns:     true if the user confirms delete, false otherwise. 
 */
function deleteGeneric ( message ){
  var doSubmit = false;
  if ( confirm ( message ) ){ 
    doSubmit = true;
  }
  return doSubmit;
}

/**
 * Function:    addGroup
 * Description: Validates the group id entered by the user before submiting the form
 * Parameters:  none
 * Returns:     true if the group id is valid, so that the form is submited,
 *              false otherwise. 
 */
function addGroup( groups ){
  var doSubmit = addGeneric( groups, 'inputGroupID' );
  return doSubmit;
}

/**
 * Function:    editGroup
 * Description: If the button pressed was "Edit", makes the form fields editable. 
 *              If the button pressed was "Save", simply submits the form.
 * Parameters:  who: id of the line to edit/save
 * Returns:     true if the button pressed was save, so that the form is submited, 
 *              false otherwiser. 
 */
function editGroup( who, groups ){
  var elements = [
                   'inputGroupID', 
                   'inputGroupName'
                 ];
  var doSubmit = editGeneric( who, groups, elements );
  return( doSubmit );
  /*
  var doSubmit = false;
  var what = document.getElementById( 'buttonSave' + who ).value;
  //alert( "what: " + what + " who: " + who );
  if( what == 'Save' ){
    doSubmit = true; //We're saving, that's php business
  } else if ( what == 'Edit' ){ //Editing: enable fields
    document.getElementById( 'inputGroupID' + who ).disabled = false;
    document.getElementById( 'inputGroupID' + who ).readOnly = true;
    document.getElementById( 'inputGroupName' + who ).disabled = false;
    document.getElementById( 'buttonSave' + who ).value = "Save";
    for( i = 0; i < groups.length; i++ ){
      if( groups[i] != who ){
        document.getElementById( 'buttonSave' + groups[i] ).disabled = true;    
      }
    }
   }
  return( doSubmit );
  */
}

/**
 * Function:    deleteGroup
 * Description: ask for confirmation before submiting the form.
 * Parameters:  none
 * Returns:     true if the user confirms delete, false otherwise. 
 */
function deleteGroup(){
  var doSubmit = deleteGeneric( "This will delete the selected group" + 
              "\nClick Ok to proceed, Cancel otherwise" );
  return doSubmit;
}

/**
 * Function:    addLinkCategory
 * Description: Validates the link category id entered by the user before submiting the form
 * Parameters:  categories: array containing the existing categories
 * Returns:     true if the link category id is valid, so that the form is submited,
 *              false otherwise. 
 */
function addLinkCategory( categories ){
  var doSubmit = addGeneric( categories, 'inputLinkCategoryID' );
  return doSubmit;
}

/**
 * Function:    editCategory
 * Description: If the button pressed was "Edit", makes the form fields editable. 
 *              If the button pressed was "Save", simply submits the form.
 * Parameters:  who: id of the line to edit/save
 * Returns:     true if the button pressed was save, so that the form is submited, 
 *              false otherwiser. 
 */
function editCategory( who, categories ){
  var elements = [
                   'inputLinkCategoryID', 
                   'linkCategoryText', 
                   'selectParentCategoryID', 
                   'selectGroup'
                 ];
  var doSubmit = editGeneric( who, categories, elements );
  return( doSubmit );
  /*
  var doSubmit = false;
  var what = document.getElementById( 'buttonSave' + who ).value;
  if( what == 'Save' ){
    doSubmit = true; //We're saving, that's php business
  } else if ( what == 'Edit' ){ //Editing: enable fields
    document.getElementById( 'inputLinkCategoryID' + who ).disabled = false;
    document.getElementById( 'inputLinkCategoryID' + who ).readOnly = true;
    document.getElementById( 'linkCategoryText' + who ).disabled = false;
    document.getElementById( 'selectParentCategoryID' + who ).disabled = false;
    document.getElementById( 'selectGroup' + who ).disabled = false;
    document.getElementById( 'buttonSave' + who ).value = "Save";
    //alert ( categories );
    for( i = 0; i < categories.length; i++ ){
      if( categories[i] != who  && categories[i] != 'Root Item'){
        document.getElementById( 'buttonSave' + categories[i] ).disabled = true;    
      }
    }
   }
  return( doSubmit );*/
}

/**
 * Function:    deleteCategory
 * Description: ask for confirmation before submiting the form.
 * Parameters:  none
 * Returns:     true if the user confirms delete, false otherwise. 
 */
function deleteCategory(){
  var doSubmit = false;
  if (confirm("This will delete the selected category and all of its children" + 
              "\nClick Ok to proceed, Cancel otherwise" ) ){ 
    doSubmit = true;
  }
  return doSubmit;
}

/**
 * Function:    seeCategory
 * Description: shows the links belonging to a certain category.
 * Parameters:  category: id of the category to show.
 * Returns:     none
 */
function seeCategory( category ){
  location.href = 'Array' + '?cat=' + escape( category );
  //alert ( location.href );
}

/**
 * Function:    addLink
 * Description: Validates the link id entered by the user before submiting the form
 * Parameters:  lins: array containing the existing links
 * Returns:     true if the link category id is valid, so that the form is submited,
 *              false otherwise. 
 */
function addLink( links ){
  var doSubmit = addGeneric( links, 'inputLinkID' );
  /*
  if( doSubmit ){
    //Validate URL entered in INPUT_LINKTO
    url = document.getElementById( 'inputLinkTo');
    myAlert( "Url: " + url );
    regex = /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$/;
    myAlert( "RegEx: " + regex );
    if (regex.test( url.value )) {
      doSubmit = true;
      //alert( "Valid url" );
    }
    else {
      alert( "The url you entered already is not valid!!!" );
      url.focus();
    }
  }
  else{*/
  return doSubmit;
}

/**
 * Function:    editLink
 * Description: If the button pressed was "Edit", makes the form fields editable. 
 *              If the button pressed was "Save", simply submits the form.
 * Parameters:  who: id of the line to edit/save
 * Returns:     true if the button pressed was save, so that the form is submited, 
 *              false otherwiser. 
 */
function editLink( who, links ){
  var elements = [
                   'inputLinkID', 
                   'selecteCategoryID',
                   'inputLinkTo',
                   'selectLinkTarget',
                   'inputLinkText',
                   'selectGroup'
                 ];
  var doSubmit = editGeneric( who, links, elements );
  return( doSubmit );
  /*
  var doSubmit = false;
  var what = document.getElementById( 'buttonSave' + who ).value;
  //alert( "what: " + what + " who: " + who );
  if( what == 'Save' ){
    //Validate URL entered in INPUT_LINKTO
    /*url = document.getElementById( 'inputLinkTo');
    regex = /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$/;
    if (regex.test( url.value )) {
      doSubmit = true;
      alert( "Valid url" );
    } else {
      alert( "The url you entered already is not valid!!!" );
      url.focus();
    } */
/*    doSubmit = true;
  } else if ( what == 'Edit' ){ //Editing: enable fields
    document.getElementById( 'inputLinkID' + who ).disabled = false;
    document.getElementById( 'inputLinkID' + who ).readOnly = true;
    document.getElementById( 'selecteCategoryID' + who ).disabled = false;
    document.getElementById( 'inputLinkTo' + who ).disabled = false;
    document.getElementById( 'selectLinkTarget' + who ).disabled = false;
    document.getElementById( 'inputLinkText' + who ).disabled = false;
    document.getElementById( 'selectGroup' + who ).disabled = false;
    document.getElementById( 'buttonSave' + who ).value = "Save";
    for( i = 0; i < links.length; i++ ){
      if( links[i] != who  && links[i] != 'Root Item'){
        document.getElementById( 'buttonSave' + links[i] ).disabled = true;    
      }
    }
   }
  return( doSubmit );*/
}

/**
 * Function:    deleteLink
 * Description: ask for confirmation before submiting the form.
 * Parameters:  none
 * Returns:     true if the user confirms delete, false otherwise. 
 */
function deleteLink(){
  var doSubmit = deleteGeneric( "This will delete the selected link" + 
              "\nClick Ok to proceed, Cancel otherwise" );
  return doSubmit;
}

/**
 * Function:    addQuote
 * Description: Validates the id entered by the user before submiting the form
 * Parameters:  quotes: array containing the existing quotes
 * Returns:     true if the id is valid, so that the form is submited,
 *              false otherwise. 
 */
function addQuote( quotes ){
  var doSubmit = addGeneric( quotes, 'inputQuoteID' );
  return doSubmit;
}

/**
 * Function:    editQuotes
 * Description: If the button pressed was "Edit", makes the form fields editable. 
 *              If the button pressed was "Save", simply submits the form.
 * Parameters:  who: id of the line to edit/save
 *              quotes: array containing all existing quotes
 * Returns:     true if the button pressed was save, so that the form is submited, 
 *              false otherwiser. 
 */
function editQuote( who, quotes ){
  var elements = [
                   'inputQuoteID', 
                   'inputQuote'
                 ];
  var doSubmit = editGeneric( who, quotes, elements );
  return( doSubmit );
  /*
  var doSubmit = false;
  var what = document.getElementById( 'buttonSave' + who ).value;
  if( what == 'Save' ){
    doSubmit = true; //We're saving, that's php business
  } else if ( what == 'Edit' ){ //Editing: enable fields
    document.getElementById( 'inputQuoteID' + who ).disabled = false;
    document.getElementById( 'inputQuoteID' + who ).readOnly = true;
    document.getElementById( 'inputQuote' + who ).disabled = false;
    document.getElementById( 'buttonSave' + who ).value = "Save";
    //alert ( categories );
    for( i = 0; i < quotes.length; i++ ){
      if( quotes[i] != who  && quotes[i] != 'Root Item'){
        document.getElementById( 'buttonSave' + quotes[i] ).disabled = true;    
      }
    }
   }
  return( doSubmit );*/
}

/**
 * Function:    deleteQuote
 * Description: ask for confirmation before submiting the form.
 * Parameters:  none
 * Returns:     true if the user confirms delete, false otherwise. 
 */
function deleteQuote(){
  var doSubmit = deleteGeneric( "This will delete the selected quote" + 
              "\nClick Ok to proceed, Cancel otherwise" );
  return doSubmit;
}

/**
 * Function:    addLanguage
 * Description: Validates the id entered by the user before submiting the form
 * Parameters:  languages: array containing the existing languages
 * Returns:     true if the id is valid, so that the form is submited,
 *              false otherwise. 
 */
function addQuote( languages ){
  var doSubmit = addGeneric( languages, 'inputLanguageID' );
  return doSubmit;
}

/**
 * Function:    editLanguage
 * Description: If the button pressed was "Edit", makes the form fields editable. 
 *              If the button pressed was "Save", simply submits the form.
 * Parameters:  who: id of the line to edit/save
 *              languages: array containing all existing languages
 * Returns:     true if the button pressed was save, so that the form is submited, 
 *              false otherwiser. 
 */
function editLanguage( who, languages ){
  var elements = [
                   'inputLanguageID', 
                   'inputLanguageName'
                 ];
  var doSubmit = editGeneric( who, languages, elements );
  return( doSubmit );
  /*
  var doSubmit = false;
  var what = document.getElementById( 'buttonSave' + who ).value;
  if( what == 'Save' ){
    doSubmit = true; //We're saving, that's php business
  } else if ( what == 'Edit' ){ //Editing: enable fields
    document.getElementById( 'inputLanguageID' + who ).disabled = false;
    document.getElementById( 'inputLanguageID' + who ).readOnly = true;
    document.getElementById( 'inputLanguageName' + who ).disabled = false;
    document.getElementById( 'buttonSave' + who ).value = "Save";
    for( i = 0; i < languages.length; i++ ){
      if( languages[i] != who  && languages[i] != 'Root Item'){
        document.getElementById( 'buttonSave' + languages[i] ).disabled = true;    
      }
    }
   }
  return( doSubmit );*/
}

/**
 * Function:    deleteLanguage
 * Description: ask for confirmation before submiting the form.
 * Parameters:  none
 * Returns:     true if the user confirms delete, false otherwise. 
 */
function deleteLanguage(){
  var doSubmit = deleteGeneric( "This will delete the selected language" + 
                                "\nClick Ok to proceed, Cancel otherwise" );
  return doSubmit;
}

/**
 * Function:    addWriting
 * Description: Validates the id entered by the user before submiting the form
 * Parameters:  writing: array containing the existing writings
 * Returns:     true if the id is valid, so that the form is submited,
 *              false otherwise. 
 */
function addWriting( writings ){
  var date = document.getElementById( 'inputDate');
  var doSubmit = addGeneric( writings, 'inputWritingID' )
                 && validateDate( date );
  return doSubmit;
}

/**
 * Function:    editWriting
 * Description: If the button pressed was "Edit", makes the form fields editable. 
 *              If the button pressed was "Save", simply submits the form.
 * Parameters:  who: id of the line to edit/save
 *              writings: array containing all existing languages
 * Returns:     true if the button pressed was save, so that the form is submited, 
 *              false otherwiser. 
 */
function editWriting( who, writings ){
  var elements = [
                   'inputWritingID', 
                   'inputDate', 
                   'selectFile', 
                   'selectGroup', 
                   'selectLanguage', 
                 ];
  var date = document.getElementById( 'inputDate' + who  );
  var doSubmit = editGeneric( who, writings, elements ) &&
                 validateDate( date );
  return( doSubmit );
}


/**
 * Function:    validateDate
 * Description: validates the date entered
 * Parameters:  date: string containing the date to be validated
 * Returns:     true if the date is valid, false otherwise. 
 */
function validateDate( field ){
  var allowBlank = true;
  var minYear = 1900;
  var maxYear = (new Date()).getFullYear();
  var isValidDate = false;

  var errorMsg = "";

  // regular expression to match required date format
  re = /^(\d{4})\-(\d{1,2})\-(\d{1,2})$/;
  
  if(field.value != '') {
    if(regs = field.value.match(re)) {
      var year  = regs[1];
      var month = regs[2];
      var day   = regs[3];
      if( year < minYear || year > maxYear) {
        errorMsg = "Invalid value for year: " + field.value;
      } else if ( month < 1 || month > 12) {
        errorMsg = "Invalid value for month: " + field.value;
      } else {
        switch( month ){
          //31 days
          case  "01", "03", "05", "07", "08", "10", "12": 
            if( day < 1 || day > 31 ){
              errorMsg = "Invalid value for day: " + field.value;
            }
            break;
          //30 days
          case "04", "06", "09", "11": 
            if( day < 1 || day > 30 ){
              errorMsg = "Invalid value for day: " + field.value;
            }
            break;
          //28 days  
          case "02": 
            var maxDays = 28;
            if( year % 4 == 0 ){
              maxDays = 29;
            }
            if( day < 1 || day > maxDays ){
              errorMsg = "Invalid value for day: " + field.value;
            }
            break;
        }
      }
    } else {
      errorMsg = "Invalid date format: " + field.value;
    }
  } else if(!allowBlank) {
    errorMsg = "Empty date not allowed!";
  }
  
  if(errorMsg != "") {
    alert(errorMsg);
    field.focus();
  } else {
    isValidDate = true;
  }
  //alert( isValidDate );
  return isValidDate;  
}

/**
 * Function:    deleteWriting
 * Description: ask for confirmation before submiting the form.
 * Parameters:  none
 * Returns:     true if the user confirms delete, false otherwise. 
 */
function deleteWriting( who ){
  var doSubmit = deleteGeneric( "This will delete the selected writing" + 
                                "\nClick Ok to proceed, Cancel otherwise" );
  var file = document.getElementById( 'selectFile' + who ).value

  //See if user wants to delete the file as well.
  if( confirm( "Do you also wish to delete the file " + file + 
               "\nClick Ok to proceed, Cancel otherwise" ) ){
    document.getElementById( 'deletedFile' ).value = file;
  }
  return doSubmit;
}

/**
 * Function:    activateUploadButton
 * Description: activates the upload button once the file is selected.
 * Parameters:  none
 * Returns:     none. 
 */
function activateUploadButton(){
  document.getElementById('Upload').disabled = false;
}
