// Title: Tigra Menu PRO
// Description: Tigra Menu PRO is flexible menu solution for commercial
//        applications offering high reliability and wide browsers support.
//        See URL for complete feature list.
// URL: http://www.softcomplex.com/products/tigra_menu_pro/
// Version: 3.0
// Date: 03-12-2002 (mm-dd-yyyy)
// Notes: Registration needed to use this script legally.
//        Visit official site for details.

var o_doc,
        menus = [];
        states = ['mout', 'mover', 'mdown'];

function doc () {
        this.f_width   = window.innerWidth != null ?
                function () { return window.innerWidth } :
                function () { return document.body.clientWidth };
        this.f_height  = window.innerHeight != null ?
                function () { return window.innerHeight } :
                function () { return document.body.clientHeight };
        this.f_xscroll = window.pageXOffset != null ?
                function () { return window.pageXOffset } :
                function () { return document.body.scrollLeft };
        this.f_yscroll = window.pageYOffset != null ?
                function () { return window.pageYOffset } :
                function () { return document.body.scrollTop };
        this.get_element = document.all ?
                function (i) { return document.all[i] } :
                function (i) { return document.getElementById(i) };

        this.update = doc_update;
        this.redraw = doc_redraw;
}

function doc_update () {
        var n_value, b_refresh;

        // verify in any environment paramenters changed
        if (this.width != (n_value = this.f_width())) {
                this.width = n_value;
                b_refresh = true;
        }
        if (this.height != (n_value = this.f_height())) {
                this.height = n_value;
                b_refresh = true;
        }
        if (this.xscroll != (n_value = this.f_xscroll())) {
                this.xscroll = n_value;
                b_refresh = true;
        }
        if (this.yscroll != (n_value = this.f_yscroll())) {
                this.yscroll = n_value;
                b_refresh = true;
        }
        if (b_refresh) {
                // ignore updates until parameters are stable
                if (this.o_timer) clearTimeout(this.o_timer);
                this.o_timer = setTimeout('o_doc.redraw()', 200);
//                o_doc.redraw();
        }
        window.setTimeout('o_doc.update()', 50);
}

function doc_redraw () {
        for (var i = 0; i < menus.length; i++)
                if (menus[i].active)
                        menus[i].redraw();
}

// --------------------------------------------------------------------------------
// menu class constructor
function menu (item_struct, geom_struct) {
        this.item_struct = item_struct;
        this.geom_struct = geom_struct;
        this.items       = [];
        this.children    = [];
        this.a_position  = [];
        this.over_items  = 0;

        this.hide        = menu_hide;
        this.onclick     = menu_onclick;
        this.onmouseout  = menu_onmouseout;
        this.onmouseover = menu_onmouseover;
        this.onmousedown = menu_onmousedown;
        this.pos         = menu_position;
        this.redraw      = menu_redraw;

        // prepare environment object
        if (!o_doc) {
                o_doc = new doc();
                o_doc.update();
        }
        // register in global menus collection
        this.id = menus.length;
        menus[this.id] = this;

        // init children recursively
        for (var i = 0; i < this.item_struct.length; i++)
                new menu_item(i, this, this);

        // calculate menu sizes
        var max_x = 0,
                max_y = 0,
                min_x = Number.POSITIVE_INFINITY,
                min_y = Number.POSITIVE_INFINITY;
        for (var i = 0; i < this.children.length; i++) {
                max_x = Math.max(max_x, this.children[i].pos('left') + this.children[i].pos('width'));
                max_y = Math.max(max_y, this.children[i].pos('top')  + this.children[i].pos('height'));
                min_x = Math.min(min_x, this.children[i].pos('left'));
                min_y = Math.min(min_y, this.children[i].pos('top'));
        }

        // init sizes and positioning
        this.a_position.top = 0;
        this.a_position.left = 0;
        this.a_position.width  = max_x - min_x;
        this.a_position.height = max_y - min_y;

        this.active = true;
        this.redraw();
}


// --------------------------------------------------------------------------------
// menu methods
// --------------------------------------------------------------------------------
function menu_hide () {
        if (!this.hide_timer || this.over_items || !this.last_item)
                return;
        this.last_item.collapse(0);
        this.last_item = null;
}

function menu_redraw () {

        this.a_position.top =
        this.a_position.left = 0;

        if (this.geom_struct.align == 'center')
                this.a_position.left = Math.round((o_doc.width - this.a_position.width) / 2);
        else if (this.geom_struct.align == 'right')
                this.a_position.left = o_doc.width - this.a_position.width;

        if (this.geom_struct.valign == 'center')
                this.a_position.top = Math.round((o_doc.height - this.a_position.height) / 2);
        else if (this.geom_struct.valign == 'bottom')
                this.a_position.top = o_doc.height - this.a_position.height;

        if (this.geom_struct.scroll == 'horizontal' || this.geom_struct.scroll == 'both')
                this.a_position.left += o_doc.xscroll;
        if (this.geom_struct.scroll == 'vertical' || this.geom_struct.scroll == 'both')
                this.a_position.top += o_doc.yscroll;

        for (var i = 0; i < this.children.length; i++) {
                this.children[i].set_state('hidden', true);
                this.children[i].reposition(true);
                this.children[i].set_state('mout');
        }
}

function menu_position (coord) {
        return this.a_position[coord] ? this.a_position[coord] : 0;
}

// --------------------------------------------------------------------------------
// menu event handlers
// --------------------------------------------------------------------------------
function menu_onclick (id) {
        return (this.items[id].fields[1] ? true : false);
}

function menu_onmouseout (id) {
        this.over_items--;
        this.items[id].set_state('mout');
        if (this.items[id].expd_timer) clearTimeout(this.items[id].expd_timer);
        this.hide_timer = setTimeout('menus['+ this.id +'].hide();',
                this.geom_struct.hide_delay[this.items[id].depth]);
}

function menu_onmouseover (id) {
        this.over_items++;
        for (var item = this.items[id]; item.elements; item = item.parent) item.set_state('mover');
        clearTimeout(this.hide_timer);
        this.hide_timer = null;
        if (this.geom_struct.expd_delay && this.geom_struct.expd_delay[this.items[id].depth])
                this.items[id].expd_timer = setTimeout('menus["'+ this.id +'"].items['+ id +'].expand()',
                        this.geom_struct.expd_delay[this.items[id].depth]);
        else this.items[id].expand();
}

function menu_onmousedown (id) {
        this.items[id].set_state('mdown');
}

// --------------------------------------------------------------------------------
// menu item class constructor
// --------------------------------------------------------------------------------
function menu_item (path, parent, container) {
        this.path = new String (path);
        this.parent = parent; this.container = container;
        this.arrpath = this.path.split('_');
        this.depth = this.arrpath.length - 1;

        // get reference 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 ? 3 : 0)) + ']';
        eval('this.fields = this.container.item_struct' + struct_path);
        if (!this.fields) return;

        // register self in the collections
        this.id = this.container.items.length;
        this.container.items[this.id] = this;
        parent.children[parent.children.length] = this;

        // assign browser dependent functions
        if (document.layers) {
                this.write = mitem_lay_write;
                this.set_state = mitem_lay_state;
                this.pos = mitem_lay_position;
        }
        else {
                this.write = mitem_css_write;
                this.set_state = mitem_css_state;
                this.pos = mitem_css_position;
        }
        // assign crossbrowser functions
        this.collapse = mitem_collapse;
        this.expand = mitem_expand;
        this.reposition = mitem_reposition;

        // init self
        this.item_pos = [];
        this.elements = [];
        this.write(this.reposition(false));
        this.state = 'hidden';

        // init children recursively
        this.children = [];
        var child_count = this.fields.length - 3;
        for (var i = 0; i < child_count; i++)
                new menu_item (this.path + '_' + i, this, this.container);
}
// --------------------------------------------------------------------------------
// browser independent methods
// --------------------------------------------------------------------------------

// collapses menu to the level specified
function mitem_collapse(to_level) {
        for (var i = 0; i < this.children.length; i++)
                this.children[i].set_state('hidden');
        if (to_level >= this.depth) this.set_state('mout');
        else this.parent.collapse(to_level);
}

// expands menu to calling items
function mitem_expand() {
        if (this.container.last_item && this.depth <= this.container.last_item.depth)
                        this.container.last_item.collapse(this.container.last_item.parent == this ? this.depth+1 : this.depth);
        if (!this.container.last_item || this.container.last_item.parent != this)
            for (var i = 0; i < this.children.length; i++)
                        this.children[i].set_state('mout');
        this.container.last_item = this;
}
// calculates items position and updates it if requested
function mitem_reposition (update) {

        if (this.arrpath[this.depth] == 0) {
                this.item_pos.left = this.parent.pos('left')
                        + (this.fields[2] != null && this.fields[2][0] != null
                        ? this.fields[2][0] : this.container.geom_struct.block_left[this.depth]);
                this.item_pos.top  = this.parent.pos('top')
                        + (this.fields[2] != null && this.fields[2][1] != null
                        ? this.fields[2][1] : this.container.geom_struct.block_top[this.depth]);
        }
        else {
                this.item_pos.left = this.parent.children[this.arrpath[this.depth] - 1].pos('left')
                        + (this.fields[2] != null && this.fields[2][0] != null ? this.fields[2][0]
                        : this.container.geom_struct.left[this.depth]);
                this.item_pos.top  = this.parent.children[this.arrpath[this.depth] - 1].pos('top')
                        + (this.fields[2] != null && this.fields[2][1] != null ? this.fields[2][1]
                        : this.container.geom_struct.top[this.depth]);
        }
        this.item_pos.width  = (this.fields[2] != null && this.fields[2][2] != null
                ? this.fields[2][2] : this.container.geom_struct.width[this.depth]);
        this.item_pos.height = (this.fields[2] != null && this.fields[2][3] != null
                ? this.fields[2][3] : this.container.geom_struct.height[this.depth]);

        if (!update) return this.item_pos;
        this.pos('left', this.item_pos.left);
        this.pos('top',  this.item_pos.top);

        for (var i = 0; i < this.children.length; i++)
                this.children[i].reposition(true);
}

// --------------------------------------------------------------------------------
// CSS positioning methons version
// --------------------------------------------------------------------------------

// item initialisation
function mitem_css_write (pos) {
        for (var i = 0; i < states.length; i++) {
                document.write (
                        '<div id="m' + this.container.id + 'i' + this.id + states[i]
                        + '" style="position: absolute; left: ' + pos.left + 'px; top: '
                        + pos.top + 'px; width: ' + pos.width + 'px; height: ' + pos.height
                        + 'px; visibility: hidden; z-index: ' + this.depth * 2 + ';" class="m'
                        + this.container.id + 'l' + this.depth + states[i] + 'o"><div class="m'
                        + this.container.id + 'l' + this.depth + states[i] + 'i">'
                        + (typeof(this.fields[0]) == 'object' ? this.fields[0][i] : this.fields[0])
                        + '</div></div>');
                this.elements[states[i]] = o_doc.get_element('m' + this.container.id + 'i' + this.id + states[i]);
        }
        document.write(
                '<div id="m' + this.container.id + 'i' + this.id + 'i" style="position: absolute; left: '
                + pos.left + 'px; top: ' + pos.top + 'px; width: ' + pos.width + 'px; height: '
                + pos.height + 'px; visibility: hidden; z-index: ' + (this.depth * 2 + 1) + ';"><a href="'
                + (this.fields[1] != null && typeof(this.fields[1]) != 'string' && this.fields[1][0] != null ? this.fields[1][0] : this.fields[1])
                + '"' + (this.fields[1] != null && typeof(this.fields[1]) != 'string' && this.fields[1][1] != null ? ' target="' + this.fields[1][1]
                + '"' : '') + ' 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
                + ');"><img src="' + this.container.geom_struct['pixel_path']
                + '" width="' + pos.width +'" height="' + pos.height + '" border="0"'
                + (this.fields[1] != null && typeof(this.fields[1]) != 'string' && this.fields[1][2] != null ? ' alt="'
                + this.fields[1][2] + '"' : '') + '></a></div>');
        this.link = o_doc.get_element('m' + this.container.id + 'i' + this.id + 'i');
}

// swithces states of menu item
function mitem_css_state(state, force) {
        if (!this.depth && state == 'hidden' && !force) state = 'mout';
        if (state == this.state) return;
        if (this.state == 'hidden') this.link.style.visibility = 'visible';
        else this.elements[this.state].style.visibility = 'hidden';
        if (state == 'hidden') this.link.style.visibility = 'hidden';
        else this.elements[state].style.visibility = 'visible';
        this.state = state;
}

// sets or retreives item's position on the page
function mitem_css_position (coord, value) {
        if (!coord) return;
        if (this.link.style.pixelLeft)
                if (coord == 'left')        coord = 'pixelLeft';
                else if (coord == 'top')    coord = 'pixelTop';
                else if (coord == 'width')  coord = 'pixelWidth';
                else if (coord == 'height') coord = 'pixelHeight';

        if (value) {
                for (var i = 0; i < states.length; i++)
                        this.elements[states[i]].style[coord] = value + (this.link.style.pixelLeft?0:'px');
                this.link.style[coord] = value + (this.link.style.pixelLeft?0:'px');
                return (this.item_pos[coord] = value);
        }
        else {
                var re_num = /^(\-?\d+)/;
                if (re_num.exec(this.link.style[coord]))
                        return new Number(RegExp.$1);
        }
}

// --------------------------------------------------------------------------------
// Layers positioning methods version
// --------------------------------------------------------------------------------

// item initialisation
function mitem_lay_write (pos) {
        for (var i = 0; i < states.length; i++) {
                document.write(
                        '<layer name="m' + this.container.id + 'i' + this.id + states[i]
                        + '" left="' + pos.left + '" top="' + pos.top + '" z-index="'
                        + this.depth * 2  + '" width="' + pos.width + '" height="'
                        + pos.height + '" visibility="hide"><table cellpadding="0" cellspacing="0" border="0" width="'
                        + pos.width + '" height="' + pos.height + '" class="m'
                        + this.container.id + 'l' + this.depth + states[i] + 'o"><tr><td><div class="m'
                        + this.container.id + 'l' + this.depth + states[i] + 'o"><div class="m'
                        + this.container.id + 'l' + this.depth + states[i] + 'i">'
                        + (typeof(this.fields[0]) == 'object' ? this.fields[0][i] : this.fields[0])
                        + '</div></div></td></tr></table></layer>');
                this.elements[states[i]] = document.layers['m' + this.container.id + 'i' + this.id + states[i]];
        }
        document.write(
                '<layer name="m' + this.container.id + 'i' + this.id + 'i" left="'
                + pos.left + '" top="' + pos.top + '" z-index="' + (this.depth * 2 + 1)
                + '" visibility="hide" width="' + pos.width +'" height="' + pos.height
                + '"><a href="' + (this.fields[1] != null && typeof(this.fields[1]) != 'string' && this.fields[1][0] != null ? this.fields[1][0] : this.fields[1])
                + '"' + (this.fields[1] != null && typeof(this.fields[1]) != 'string' && this.fields[1][1] != null ? ' target="'
                + this.fields[1][1] + '"' : '')        + ' 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 + ');"><img src="' + this.container.geom_struct['pixel_path']
                + '" width="' + pos.width +'" height="' + pos.height + '" border="0"'
                + (this.fields[1] != null && typeof(this.fields[1]) != 'string' && this.fields[1][2] != null ? ' alt="'
                + this.fields[1][2] + '"' : '')        + '></a></layer>');
        this.link = document.layers['m' + this.container.id + 'i' + this.id + 'i'];
}

// swithces states of menu item
function mitem_lay_state(state) {
        if (!this.depth && state == 'hidden') state = 'mout';
        if (state == this.state) return;
        if (this.state == 'hidden') this.link.visibility = 'show';
        else this.elements[this.state].visibility = 'hide';
        if (state == 'hidden') this.link.visibility = 'hide';
        else this.elements[state].visibility = 'show';
        this.state = state;
}

// sets or retreives item's position on the page
function mitem_lay_position (coord, value) {
        if (!coord) return;
        if (value) {
                this.item_pos[coord] = value;
                for (var i = 0; i < states.length; i++) {
                        this.elements[states[i]].moveTo   (this.item_pos.left, this.item_pos.top);
                        this.elements[states[i]].resizeTo (this.item_pos.width, this.item_pos.height);
                }
                this.link.moveTo   (this.item_pos.left, this.item_pos.top);
                this.link.resizeTo (this.item_pos.width, this.item_pos.height);
        }
        return this.item_pos[coord];
}

// --------------------------------------------------------------------------------
// that's all folks