var menus = [];

var w_Width,w_Height;
var start_x = 0, start_y = 0;

function findPos(obj) {
   var curleft = curtop = 0;
   if (obj.offsetParent) {
      curleft = obj.offsetLeft
      curtop = obj.offsetTop
      while (obj = obj.offsetParent) {
         curleft += obj.offsetLeft
         curtop += obj.offsetTop
      }
   }
   return [curleft,curtop];
}

// ------------------
// --- menu class ---
function menu (item_struct, pos, styles, classes, posxy, debug) {

   start_x = posxy[0];
   start_y = posxy[1];

   if(debug) alert("START X:"+start_x );
   if(debug) alert("START Y:"+start_y );

   // browser check
   this.item_struct = item_struct;
   this.pos = pos;
   this.styles = styles;
   this.classes = classes;
   this.id = menus.length;
   this.items = [];
   this.children = [];

   // --- Inizializza i metodi ---
   this.add_item = menu_add_item;
   this.hide = menu_hide;
   this.onclick = menu_onclick;
   this.onmouseout = menu_onmouseout;
   this.onmouseover = menu_onmouseover;
   this.onmousedown = menu_onmousedown;
   this.posrel_x = 0;
   this.posrel_y = 0;

   var i;
   for (i = 0; i < this.item_struct.length; i++) new menu_item(i, this, this, debug);
   for (i = 0; i < this.children.length; i++) this.children[i].visibility(true);
   menus[this.id] = this;
}

function menu_add_item (item) {
   var id = this.items.length;
   this.items[id] = item;
   return (id);
}

function menu_hide () {
   for (var i = 0; i < this.items.length; i++) {
      this.items[i].visibility(false);
      this.items[i].switch_class('onmouseout');
   }
}

function menu_onclick (id) {
   var item = this.items[id];
   return (item.fields[1] ? true : false);
}

function menu_onmouseout (id) {
   this.hide_timer = setTimeout('menus['+ this.id +'].hide();',
   this.pos['hide_delay'][this.active_item.depth]);
   if (this.active_item.id == id)  this.active_item = null;
}

function menu_onmouseover (id) {
   this.active_item = this.items[id];
   clearTimeout(this.hide_timer);
   var curr_item, visib;
   for (var i = 0; i < this.items.length; i++) {
      curr_item = this.items[i];
      visib = (curr_item.arrpath.slice(0, curr_item.depth).join('_') ==  this.active_item.arrpath.slice(0, curr_item.depth).join('_'));
      if (visib)  curr_item.switch_class (curr_item == this.active_item ? 'onmouseover' : 'onmouseout');
      curr_item.visibility(visib);
   }
}

function menu_onmousedown (id) {
   this.items[id].switch_class('onmousedown');
}

// -----------------------
// --- menu item Class ---
function menu_item (path, parent, container, debug) {
   this.path = new String (path); // this.path è una stringa del tipo '1_1_2'
   this.parent = parent;
   this.container = container;

   this.arrpath = this.path.split('_'); // this.arrpath è un array del tipo ['1','1','2']
   this.depth = this.arrpath.length - 1;

   // get pointer to item s data in the structure
   var struct_path = '';
   for (var i = 0; i <= this.depth; i++)
      struct_path += '[' + (Number(this.arrpath[i]) + (i ? 5 : 0)) + ']';

   eval('this.fields = this.container.item_struct' + struct_path);

   if (!this.fields) return;
   if (this.fields[1]==null && this.depth>0) return;

   // INIZIALIZZAZIONE DEI METODI
   // these methods may be different for different browsers (i.e. non DOM compatible)
   this.init = mitem_init;
   this.visibility = mitem_visibility;
   this.switch_class = mitem_switch_class;

   // register in the collections
   this.id = this.container.add_item(this);
   parent.children[parent.children.length] = this;

   this.posizione_x = start_x + parent.posrel_x;
   this.posizione_y = start_y + parent.posrel_y;

   for (var i = 0; i <= this.depth; i++)
      this.posizione_x += this.container.pos['block_left'][i];
   this.posrel_x = parent.posrel_x;

   for (var i = 0; i <= this.depth; i++)
      this.posizione_y += this.container.pos['block_top'][i];
   this.posrel_y = parent.posrel_y;

   if(this.container.pos['ori'][this.depth]=='h') {
   // Estrazione dal campo fields[3] del valore dell''attributo di stile 'width' e incremento della proprietà 'posrel_x' di parent
       var matched = /.?width:(.*)px;/i.exec(this.fields[3]);
       if(matched==null) this.fields[3] += "width:"+this.container.pos['width'][this.depth]+";";
   // Se non è definito il parametro 'width' si legge il valore dalla proprietà 'width' di MENU_POS_x
       parent.posrel_x += (matched==null)?this.container.pos['width'][this.depth]:parseInt(matched[1]);
   }

   if(this.container.pos['ori'][this.depth]=='v') {
   // Estrazione dal campo fields[3] del valore dell''attributo di stile 'height' e incremento della proprietà 'posrel_y' di parent
       var matched = /.?height:(.*)px;/i.exec(this.fields[3]);
       if(matched==null) this.fields[3] += "height:"+this.container.pos['height'][this.depth]+";";
   // Se non è definito il parametro 'height' si legge il valore dalla proprietà 'height' di MENU_POS_x
       parent.posrel_y += (matched==null)?this.container.pos['height'][this.depth]:parseInt(matched[1]);
   }

   // if(debug) alert(parent.posrel_x+","+parent.posrel_y);

   // INIZIALIZZAZIONE (costruisce un elemento <a></a>)
   this.init(debug);

   this.children = [];
   var child_count = this.fields.length - 5;
   for (var i = 0; i < child_count; i++) {
      new menu_item (this.path + '_' + i, this, this.container, debug);
   }

   this.switch_class('onmouseout');
}

function mitem_init(debug) {
        var href = (this.fields[1]==null)?'':this.fields[1];
        var iclass = (this.fields[2]==null)?'':this.fields[2];
        var style = (this.fields[3]==null)?'':this.fields[3];
        var link = '<div id="mi_' + this.container.id + '_' + this.id +'" '
            + 'class="' + iclass + '" '
            + 'style="'+ style + ' '
            + 'z-index:' + 10 + this.depth + ';'
            + 'position:absolute; ' + 'top:'+ this.posizione_y + 'px; left:' + this.posizione_x + 'px; '
            + 'visibility: hidden;">'
            + '<a href="' + href + '" '
            + 'onclick="return menus[' + this.container.id + '].onclick('+ this.id + ');" '
            + 'onmouseout="menus[' + this.container.id + '].onmouseout('+ this.id + ');" '
            + 'onmouseover="menus[' + this.container.id + '].onmouseover('+ this.id + ');" '
            + 'onmousedown="menus[' + this.container.id + '].onmousedown('+ this.id + ');" '
            + '>'
            + this.fields[0] + '</a></div>';

   //if(debug) alert(link);
   document.write(link);

   this.element = document.getElementById('mi_' + this.container.id + '_' + this.id);
}

function mitem_visibility(make_visible) {
   if (make_visible != null) {
      if (this.visible == make_visible) return;
      this.visible = make_visible;
      if (make_visible) this.element.style.visibility = 'visible';
      else if (this.depth) this.element.style.visibility = 'hidden';
   }
   return (this.visible);
}

function mitem_switch_style(state) {
   if (this.state == state) return;
   this.state = state;
   var style = this.container.styles[state];
   for (var i = 0; i < style.length; i += 2)
      if (style[i] && style[i+1]){
         eval('this.element.style.' + style[i] + "='" + style[i+1][this.depth] + "';");
      }
}

function mitem_switch_class(state) {
   if (this.state == state) return;
   this.state = state;
   var theclass = this.container.classes[state];
   //alert(this.element.id+"--> this.element.class='" + theclass[this.depth] + "';");
   eval("this.element.className='" + theclass[this.depth] + "';");
}