/*******************************************************************************
 *
 * Title:   Constructor for two-level menu of bulgaria-nato.org.
 *
 * Version: 2.1, stable.
 *
 * Description:   This file allows you to construct a two level menu. It consist
 *    of a Constructor function and four methods described bellow. The menu is
 *    driven by an initializing array, which structure is described right after.
 *    The menu allows implementation of stylesheets for top performance.
 *
 * Legal:   This file is designed and created for www.bulgaria-nato.org by
 *    Informational Agency Focus. You can NOT use in any way this file without
 *    the explicit permission by the Author. Any violation will be prosecuted!
 *
 * Author:  Petko Georgiev.
 *
 * E-mail:  _georgiev@yahoo.com
 *
 ******************************************************************************/


/*******************************************************************************
 *
 * Init Array Structure, shown with a working example:
 *
 * aInit                   = new Object();         -- declare a object
 * aInit.optionS           = new Object();         -- object for options to pass
 * aInit.lines             = new Array();          -- array for rows
 *
 * || options available to be set ||
 *
 * aInit.optionS.timeout   = 1000;                 -- timeout // 1000 == 1 sec
 * aInit.optionS.sMainImgN = "Images/main_off.gif";-- main cat normal left image
 * aInit.optionS.sMainImgA = "Images/main_on.gif"; -- main cat active left image
 * aInit.optionS.sSubImgN  = "Images/sub_off.gif"; -- sub cat normal left image
 * aInit.optionS.sSubImgA  = "Images/sub_on.gif";  -- sub cat active left image
 * aInit.optionS.sMainCSS  = "mainStyle";          -- main cat stylesheet
 * aInit.optionS.sSubCSS   = "subStyle";           -- sub cat stylesheet
 * aInit.optionS.border    = 6;                    -- border in px
 * aInit.optionS.borderClr = "blue";               -- border color
 *
 * || no other options available in this version ||
 *
 *
 * || a good way to init lines ||
 *
 * aInit.lines[0]                = new Object();         -- declare first object
 * aInit.lines[0].main           = new Object();         -- declare main object
 * aInit.lines[0].main.href      = "http://www.focus-news.net";   -- some href
 * aInit.lines[0].main.text      = "focus-news";         -- some text
 *
 * aInit.lines[0].sub            = new Array();          -- subCtagories' array
 * aInit.lines[0].sub[0]         = new Array();          -- first sub's array
 * aInit.lines[0].sub[0]['href'] = "http://www.google.com";    -- some href
 * aInit.lines[0].sub[0]['text'] = "<B>google";          -- some text
 * aInit.lines[0].sub[1]         = new Array();          -- second sub's array
 * aInit.lines[0].sub[1]['href'] = "http://www.phrack.org";    -- some href
 * aInit.lines[0].sub[1]['text'] = "phrack.org";         -- some text
 *
 *
 * --- second line analogous to the previous above
 *
 * aInit.lines[1]                = new Object();
 * aInit.lines[1].main           = new Object();
 * aInit.lines[1].main.href      = "http://www.dir.bg";
 * aInit.lines[1].main.text      = "dir.bg";
 *
 * aInit.lines[1].sub            = new Array();
 * aInit.lines[1].sub[0]         = new Array();
 * aInit.lines[1].sub[0]['href'] = "http://www.gbg.bg";
 * aInit.lines[1].sub[0]['text'] = "gbg.bg";
 *
 *
 * --- another line analogous to the first above
 *
 * aInit.lines[2]                = new Object();
 * aInit.lines[2].main           = new Object();
 * aInit.lines[2].main.href      = "http://www.data.bg";
 * aInit.lines[2].main.text      = "data.bg";
 *
 ******************************************************************************/

/*******************************************************************************
 *
 * Changes in v2.0
 *    - some bug fixes;
 *    - border option added;
 *
 ******************************************************************************/

/*******************************************************************************
 *
 * Changes in v2.1
 *    - mininmal width option added;
 *       = init in init array as 'array'.optionS.minWidth = 'desiredWidth';
 *
 ******************************************************************************/



/*******************************************************************************
 * SOME GLOBAL VARIABLES
 ******************************************************************************/
/*******************************************************************************
 * END OF GLOBAL VARIABLES
 ******************************************************************************/



/*******************************************************************************
 *
 * Title:   fcMenuConstructor
 *
 * Description:   This is the Menu constructor function. It takes as an argument
 *    the earlier declared init array of type, described above. This constructor
 *    will directly uotput the menu object at the place you call it. The source
 *    is object oriented, so it allows construction of any number of menus.
 *
 * Input:   initialization array with structure, described earlier
 *
 * Output:  Appends a menu object to the document at the place called
 *
 * Methods: This function uses four methods.
 *    Description of these methods later in the document.
 *
 ******************************************************************************/
function fcMenuConstructor() {
   var aMenu;
   if ( !(aMenu=fcMenuConstructor.arguments[0])) { // assign the init array to oMenu var
      document.write("No init array passed for menu!");
      return;
   }

   document.write("<DIV></DIV>"); // we will append the object to this div

   if (aMenu.optionS.sMainImgA || aMenu.optionS.sSubImgN || aMenu.optionS.sSubImgA) {
      var oPreloadImg_1 = new Image();
      oPreloadImg_1.src = aMenu.optionS.sMainImgA;
      var oPreloadImg_2 = new Image();
      oPreloadImg_2.src = aMenu.optionS.sSubImgN;
      var oPreloadImg_3 = new Image();
      oPreloadImg_3.src = aMenu.optionS.sSubImgA;
   }

   var oTable           = document.createElement('table'); // create a table element
   oTable.border        = 0; // set table border
   oTable.cellPadding   = 0; // set table cellpadding
   oTable.cellSpacing   = 0; // set table cellspacing
   if (aMenu.optionS.minWidth)
      oTable.width      = aMenu.optionS.minWidth; // set table cellspacing
   oTable.subCSS        = (aMenu.optionS.sSubCSS) ? aMenu.optionS.sSubCSS  : "";
   oTable.opened        = -1; // this means that nothing is open
   oTable.borderPX      = aMenu.optionS.border; // border in picxells
   oTable.borderClr     = aMenu.optionS.borderClr; // border color
   oTable.constTimeOut  = aMenu.optionS.timeout; // border color
   if (aMenu.optionS.sSubImgN)
      oTable.subImgN    = aMenu.optionS.sSubImgN; // keep normal sub image
   if (aMenu.optionS.sSubImgA)
      oTable.subImgA    = aMenu.optionS.sSubImgA; // keep active sub image
   aDiv                 = document.getElementsByTagName('div'); // and go find the last div to append the table object to
   oDiv                 = aDiv[aDiv.length - 1]; // this is the last div from the above array
   if (aMenu.optionS.border > 0) {
//      oDiv.style.paddingLeft  = aMenu.optionS.border;
      oDiv.style.paddingRight = aMenu.optionS.border;
      if (aMenu.optionS.borderClr)
         oDiv.style.backgroundColor = aMenu.optionS.borderClr; // be sure this is a color
   }
   oDiv.appendChild(oTable); // append table to the document
   iTable               = document.getElementsByTagName('table').length - 1; // count all the tables
   for ( var i = 0 ; i < aMenu.lines.length ; i++ ) { // go trough main cats in the inti array
      if (aMenu.optionS.border > 0) { // if border is about to show
         var oBorder       = oTable.insertRow(); // insert a row
         var minCells      = (aMenu.optionS.sMainImgN) ? 2 : 1; // text : left image
         while (minCells--) { // cycle
            var oBorderCell   = oBorder.insertCell(); // insert a cell
            var oBorderImg    = document.createElement('img'); // create an image
            oBorderImg.height = aMenu.optionS.border; // set image height to the border
            oBorderImg.width  = 1; // <= border
            oBorderCell.appendChild(oBorderImg); // insert the image
         }
      }


      var oRow          = oTable.insertRow(); // insert the table row element
      var oCell         = oRow.insertCell(); // insert a cell for link

      var html          =  "<A HREF=\""
                              + aMenu.lines[i].main.href +
                           "\" CLASS=\""
                              + aMenu.optionS.sMainCSS +
                           "\">"
                              + aMenu.lines[i].main.text +
                           "</A>";
      oCell.innerHTML   = html;
      oCell.width       = "100%";
      var oLink         = oCell.getElementsByTagName('a')[0]; // get the anchor to set some parameters for it
      oLink.onmouseover = fmMenuHandleOver; // mouse over handler function
      oLink.onmouseout  = fmMenuHandleOut; // mouse out handler function
      oLink.row         = oRow; // keep the row
      oLink.rowIs       = oRow.rowIndex; // mouse out handler function
      oRow.sub          = new Array(); // declare an array
      for (var k in aMenu.lines[i].sub) { // go trough sublines of the init array
         oRow.sub[k]       = new Object(); // declare as object
         oRow.sub[k].href  = aMenu.lines[i].sub[k]['href']; // keep the link
         oRow.sub[k].text  = aMenu.lines[i].sub[k]['text']; // keep the text
      }
      if (oRow.sub.length==0)
         oRow.sub          = false; // if empty no action will be taken later
      oRow.table           = oTable; // keep the table
      oRow.iTable          = iTable; // keep the table number

      if (aMenu.optionS.sMainImgN) { // the left main image is defined
         oCell             = oRow.insertCell(0); // insert a cell in front of the row
         var oImg          = document.createElement('img'); // create an image element
         oImg.src          = aMenu.optionS.sMainImgN; // set the normal image src
         oImg.srcN         = aMenu.optionS.sMainImgN; // set the normal alternative image src
         if (aMenu.optionS.sMainImgA) // the left main image is defined
            oImg.srcA      = aMenu.optionS.sMainImgA; // set the normal alternative image src
         oImg.row          = oRow; // keep the row
         oImg.rowIs        = oRow.rowIndex; // mouse out handler function
         oImg.onmouseover  = fmMenuHandleOver; // define mouse over handler
         oImg.onmouseout   = fmMenuHandleOut; // define mouse over handler
         oCell.appendChild(oImg); // append the image to the cell
      }
   }

   // commented well earlier
   if (aMenu.optionS.border > 0) {
      var oBorder       = oTable.insertRow();
      var minCells      = (aMenu.optionS.sMainImgN)?2:1; // text : left image
      while (minCells--) {
         var oBorderCell   = oBorder.insertCell();
         var oBorderImg    = document.createElement('img');
         oBorderImg.height = aMenu.optionS.border;
         oBorderImg.width  = 1;
         oBorderCell.appendChild(oBorderImg);
      }
   }
}

/*******************************************************************************
 *
 * Title:   fmMenuHandleOver
 *
 * Description:   A method of the menu constructor. This function handles mouse
 *    over events of first level rows. It clears the timeout (if set) for second
 *    level rows to close. It also closes a group of second level rows if other
 *    first level row has to show (a group of) second level row(s).
 *       It then appends the subrows (if exist) to the appropriate place.
 *
 * Input:   no
 *
 * Output:  Appends submenu to the menu object, after the main menu row.
 *
 ******************************************************************************/
function fmMenuHandleOver() {
   if (this.row.table.timeOut)
      clearTimeout(this.row.table.timeOut); // clear the time out set on mouse out event

   if (this.row.table.opened != -1 && this.row.table.opened != this.row.rowIndex) {
      clearTimeout(this.row.table.timeOut); // clear the time out set on mouse out event
      fMenuCloseSub(this.row.iTable, this.row.table.opened); // close imideately
   }

   var oImg       = this.row.table.rows[this.rowIs].getElementsByTagName('img');
   if (oImg.length)
      oImg[0].src = oImg[0].srcA;

   if (this.row.table.opened<0) {
      for ( var i in this.row.sub) { // go trough main cats in the init array

         // commented well earlier
         if (this.row.table.borderPX > 0) {
            var oBorder       = this.row.table.insertRow(this.row.rowIndex + 2*(Number(i)+1));
            var minCells      = (this.row.table.subImgN)?2:1; // text : left image
            while (minCells--) {
               var oBorderCell   = oBorder.insertCell();
               var oBorderImg    = document.createElement('img');
               oBorderImg.height = this.row.table.borderPX;
               oBorderImg.width  = 1;
               oBorderCell.appendChild(oBorderImg);
            }
            oRow              = this.row.table.insertRow(this.row.rowIndex + 2*(Number(i)+1)); // insert a table row element
         } else
            oRow              = this.row.table.insertRow(this.row.rowIndex+1+Number(i)); // insert a table row element
         
         var oCell            = oRow.insertCell(); // insert a cell for image

         if (this.row.table.subImgN) { // the left sub image is defined
            var oImg          = document.createElement('img'); // create an image element
            oImg.src          = this.row.table.subImgN; // set the normal image src
            oImg.srcN         = this.row.table.subImgN; // set the normal image src
            if (this.row.table.subImgA) // the left sub image alternative is defined
               oImg.srcA      = this.row.table.subImgA; // set the normal image src
            oImg.row          = this.row; // keep the row
            oImg.rowIs        = oRow.rowIndex; // 
            oImg.onmouseover  = fmMenuHandleOver_sub; // define mouse over handler
            oImg.onmouseout   = fmMenuHandleOut; // define mouse over handler
            oCell.appendChild(oImg); // append the image to the cell
         }

         oCell             = oRow.insertCell(); // insert a cell for link
         var html          =  "<A HREF=\""
                                 + this.row.sub[i].href +
                              "\" CLASS=\""
                                 + this.row.table.subCSS +
                              "\">"
                                 + this.row.sub[i].text +
                              "</A>";
         oCell.innerHTML   = html;
         var oLink         = oCell.getElementsByTagName('a')[0]; // get the anchor to set some parameters for it
         oLink.onmouseover = fmMenuHandleOver_sub; // mouse over handler function
         oLink.onmouseout  = fmMenuHandleOut; // mouse out handler function
         oLink.row         = this.row; // 
         oLink.rowIs       = oRow.rowIndex; // 
      }
      this.row.table.opened   = this.row.rowIndex; // keep the index to know what is going on
   }
}

/*******************************************************************************
 *
 * Title:   fmMenuHandleOver_sub
 *
 * Description:   A method of the menu constructor. This function handles mouse
 *    over events of second level rows.
 *       It sets the active left image (if one).
 *       It then clears the timeout of its closing.
 *
 * Input:   no
 *
 * Output:  Swaps the src for an image.
 *
 ******************************************************************************/
function fmMenuHandleOver_sub() {
   var oImg       = this.row.table.rows[this.rowIs].getElementsByTagName('img');
   if (oImg.length)
      oImg[0].src = oImg[0].srcA;

   if (this.row.table.timeOut)
      clearTimeout(this.row.table.timeOut); // clear the time out set on mouse out event
}

/*******************************************************************************
 *
 * Title:   fmMenuHandleOut
 *
 * Description:   A method of the menu constructor. This function handles mouse
 *    out events of first and second level rows.
 *       It sets the normal left image (if one).
 *       It then sets the timeout to close the submenu.
 *
 * Input:   no.
 *
 * Output:  Swaps the src for an image.
 *
 ******************************************************************************/
function fmMenuHandleOut() {
   var oImg       = this.row.table.rows[this.rowIs].getElementsByTagName('img');
   if (oImg.length)
      oImg[0].src = oImg[0].srcN;
   this.row.table.timeOut  = setTimeout("fMenuCloseSub("+this.row.iTable+", "+this.row.rowIndex+")", this.row.table.constTimeOut);
}

/*******************************************************************************
 *
 * Title:   fMenuCloseSub
 *
 * Description:   A method of the menu constructor.
 *    This function handles a submenu closing.
 *
 * Input:   iTable   -- the number (in the document array) of the table used
 *          iRow     -- the number (in the table array) of the row to operate
 *
 * Output:  Deletes a single submenu of the menu object.
 *
 ******************************************************************************/
function fMenuCloseSub(iTable, iRow) {
   var oTable  = document.getElementsByTagName('table')[iTable]; // this is the table
   var oRow    = oTable.rows[iRow]; // this is the row we need to cycle
   iRow++; // increment to point to the next row
   for ( var i in oRow.sub ) // go through main cats in the init array
      oTable.deleteRow(iRow); // and delete a row
   if (oTable.borderPX > 0) // if border is set
      for ( var i in oRow.sub ) // go through main cats in the init array
         oTable.deleteRow(iRow); // and delete a row
   oTable.opened   = -1; // now everything has to be closed
}