
// ID suffixes: name + suffix = control id

var sfx_nav_group_container = '_fdiv';
var sfx_item_title = '_ttl';
var sfx_dropdown = '_dd';
var sfx_nostyle = '_nc';
var sfx_errmsg = '_msg';
var syserrmsg_id = 'syserr';

// Tags

var nav_group_tag = 'li';
var group_tags = 'div';
var nav_containers = 'mg';

// CSS Classes

var css_changebars = 'change';
var css_item_draghandle = 'mh';
var css_group_draghandle = 'gh';
var css_divider_item = 'divider';
var css_draft = 'draft';
var css_private = 'private';
var css_nav_item = 'mi';
var css_nav_item_tplt = 'tplt';
var css_errorbox = 'errbox';
var css_disabled = 'disabled';
var css_page_item = '_1im';
var css_cat_item = '_2im';
var css_user_item = '_6im';
var css_elink_item = '_5im';
var css_llink_item = '_3im';
var css_nav_group_dropzone = 'zone';
var css_noshow = 'nsh';
var css_level = 'lv';
var css_alias_error = 'xe0';
var css_plaintext_error = 'xe1';
var css_extern_url_error = 'xe2';
var css_avatar_url_error = 'xe3';
var css_image_class_error = 'xe4';
var css_deleted = 'deleted';

// Maximums
var max_group_name = 25;
var max_alias_name = 27;
var max_url_name = 80;
var max_schemes = 5;
var max_levels = 4;

// Misc
var name_delimiter = '_';
var field_separator = '-';
var id_mapvar = 'mapdef';
var vu_cookie = 'navt_lastview';
var vu_all = 0;

// ajax return codes
var xml_success = 0;
var xml_cfg_not_updated = 1;
var xml_cfg_missing_data = 2;
var xml_cfg_bad_data = 3;

var id_default_group = 'UNASSIGNED';
var id_page_wrapper = 'mgrps';
var id_sys_textbox = 'sectionName';

// Navigation item types
var item_is_category = '2';
var item_is_divider = '4';
var item_is_elink = '5';
var item_is_page = '1';
var item_is_link = '3';
var item_is_author = '6';

var vu_select = 'vuselect';
var view_all = 0;
var view_pages = 1;
var view_pages_cats = 2;
var view_cats = 3;
var view_users = 4;
var view_links = 5;
var view_hidden = 6;


// Function constants

var _close   = 0x02;
var _open    = 0x04;
var _read    = 0x06;
var _write   = 0x08;
var _clear   = 0x0a;
var _show    = 0x0c;
var _set     = 0x0e;
var _get     = 0x10;
var _updated = 0x12;
var _error   = 0x14;
var _reset   = 0x16;
var _init    = 0x18;
var _enable  = 0x1a;
var _disable = 0x1c;
var _hide =    0x1d;
var _focus =   0x1e;
var _cksize =  0x1f;


// initialize classes for Navigation Groups and Items
var NavGroup = Class.create();
var NavItem = Class.create();
var NavItemOptions = Class.create();
var resumeQ = Class.create();
var gDropZone = Array();

// For building queues of callback functions w/arguments
resumeQ.prototype = {

    initialize: function() {
        this.a = new Array();
        return;
    },

    set_callback: function(cb, arg) {
        if( cb ) {
            var o = new Object;
            o.fn = cb;
            o.arg = arg;
            this.a.push(o);
        }
    },

    exec: function() {
        for(var x = 0; x <= this.a.length; x++ ) {
            var o = this.a.pop();
            if( o ) {
                o.fn(o.arg);
            }
        }
        return;
    }
};

var rQ = new resumeQ;

// -------------------------------------------------------------------------
// NavGroup Class
// Manages a navigation group
//
// @since 95.30
// -------------------------------------------------------------------------
NavGroup.prototype = {

    initialize: function(name) {

        // php constants
        this.id_sys_textbox = 'sectionName';
        this.id_group_template = 'xyzzy';
        this.id_schemez = 'schemez';
        this.sfx_nav_group_rename = '_mmenu';
        this.sfx_nav_group_header = '_gn';
        this.sfx_nav_group_delete = '_mdele';
        this.sfx_nav_item_alias_tbx =  '_rtbx';
        this.sfx_group_option = '_gopt';
        this.has_dropdown_style = 32;
        this.has_nostyle = 2048;
        this.dropdown_menu_item  = 'Create HTML Select';
        this.nostyle_menu_item  = 'Exclude tag styles';
        this.css_new_nav_group = 'new';
        this.css_group_scheme = 'cs';

        // initialize the class
        if(name && !name.isEmpty()) {
            this.id = name;
            this.set_rootname();
            this.default_container = id_default_group + sfx_nav_group_container;
            this.set_group_ids();
        }
        return;
    },

    /** sets various DOM ids used by this class
    **/
    set_group_ids: function() {
        this.container_id = this.root + sfx_nav_group_container;
        this.deletebox_id = this.root + this.sfx_nav_group_delete;
        this.renamebox_id = this.root + this.sfx_nav_group_rename;
        this.grouptbx_id = this.root + this.sfx_nav_item_alias_tbx;
        this.navlist_id = this.root + this.sfx_nav_group_header;
        this.gopt_id = this.root + this.sfx_group_option;
        this.errbox_id = this.root + sfx_errmsg;
        this.dd_menu_item_id = this.root + sfx_dropdown;
        this.nostyle_menu_item_id = this.root + sfx_nostyle;
        this.options_menu_id = this.root + '_list';

        if( jQuery('#' + this.container_id).isPresent() ) {
            this.goptions = jQuery('#' + this.gopt_id).getIntValue();
        }
        return;
    },

    /** Extract the base name of this navigation group
    **/
    set_rootname: function() {
        var tmp = new String(this.id);
        var r = tmp.split(name_delimiter);
        this.root = r[0];
    },

    /** Create a new navigation group
    **/
    createGroup: function() {
        this.syserr(_close);
        this.sys_textbox(_reset);

        if(!this.root.isAlpha()) { // alphanueric only
            this.syserr(_set, ":: Invalid Name ::");
        }
        else if(this.isDuplicateGroupName(this.root)) {
            this.syserr(_set, ":: Duplicate Name ::");
        }
        else {
            var oldname = this.id_group_template;
            var newname = this.root;
            var clone = jQuery('#' + this.id_group_template).clone(true).each(function() {renameElement(this, oldname, newname);});
            clone.id = this.root;
            jQuery('#' + id_page_wrapper).append(clone);
            jQuery('#' + this.navlist_id).text(this.root.toLowerCase());
            this.set_scheme();
            open_window(this.root, createSortables);
        }
        return;
    },

    /** Ok to rename the navigation group
    **/
    renameOk: function() {
        this.group_textbox(_reset);
        var t = this.group_textbox(_get);
        var new_name = t.cleanGroupName();
        new_name = new_name.toUpperCase(); // force to upper case

        if( new_name.isEmpty() || !new_name.isAlpha() ) { // alphanumeric only
            this.group_textbox(_error, ":: Invalid Name ::");
        }
        else if(this.root != new_name) {
            if( this.isDuplicateGroupName(new_name) ) {
                this.group_textbox(_error, ":: Duplicate Name ::");
            }
            else {
                var cur_name = this.root;
                var node = jQuery('#' + this.root);
                jQuery('#' + this.root+this.sfx_nav_group_header).text(new_name.toLowerCase());

                // selector syntax: # + id + * = all descendants of #id
                var all = jQuery('#' + this.root + ' *').each(function() { // jquery 1.2.1
                    if( this.id !== '' ) {
                        nameNode(this, cur_name, new_name);
                    }
                });

                this.root = node[0].id = new_name;

                // reset group information for this object
                this.set_group_ids();
                this.mark_changed();
                this.errbox(_close);

                gUpdate_group_behaviors = gUpdate_navitem_behaviors = 1;
                rQ.set_callback(createSortables);
                close_window(this.renamebox_id, execute_callbacks);
            }
        }
        else {
            this.renameClose();
        }
        return;
    },

    /** Rename group cancelled
    **/
    renameClose: function() {
        this.errbox(_close);
        this.rename_controls(_close, 'end');
        return;
    },

    /** Opens/closes rename controls
    **/
    rename_controls: function(c) {
        if( c == _open ) {
            if( !(jQuery('#' + this.renamebox_id).isVisible())) {
                this.group_textbox(_set, this.root.toLowerCase());
                this.errbox(_close);
                open_window(this.renamebox_id);
            }
        }
        else if( c == _close ) {
            if( jQuery('#' + this.renamebox_id).isVisible() ) {
                this.errbox(_close);
                close_window(this.renamebox_id);
            }
        }
        return;
    },

    /** Ok to dispay conditions
    **/
    conditionsOk: function() {
        this.conditionsClose();
        return;
    },

    /** Delete group (ok button)
    **/
    deleteOk: function() {
        rQ.set_callback(do_adoption, this.root);
        close_window(this.root, execute_callbacks);
        return;
    },

    delete_group: function(group_name) {
        var me = this;

        jQuery('#' +  group_name + sfx_nav_group_container + ' .' + css_nav_item).
        each(function() {
            var navItem = new NavItem(this.id);
            if( navItem.type != item_is_divider ) {
                var clone = jQuery('#' +  navItem.container_id).clone(true);
                jQuery('#' + navItem.container_id).remove();
                me.insert_navitem(clone);
            }
            else {
                jQuery('#' + navItem.container_id).remove();
            }
        });

        jQuery('#' + group_name).remove();
        rebuild_groups();
        createSortables();
        return;
    },

    /** Delete group (cancel button)
    **/
    deleteClose: function() {
        this.errbox(_close);
        this.delete_controls(_close);
        return;
    },

    /** Opens/closes delete controls
    **/
    delete_controls: function(c) {
        if( c == _open ) {
            if( !(jQuery('#' + this.deletebox_id).isVisible()) ) {
                this.errbox(_close);
                open_window(this.deletebox_id);
            }
        }
        else if( c == _close ) {
            if( jQuery('#' + this.deletebox_id).isVisible() ) {
                this.errbox(_close);
                close_window(this.deletebox_id);
            }
        }
        return;
    },

    /** Insert a navigation item
    **/
    insert_navitem: function(item) {
        jQuery('#' + this.container_id).append(item);
        this.mark_changed();
        return;
    },

    /** Toggles the checkmark on the dropdown menu item
    **/
    toggle_dropdown: function() {
        if( !(this.goptions & this.has_dropdown_style) ) {
            jQuery('#' + this.dd_menu_item_id).set_contents('&radic; ' + '<a href="#">' + this.dropdown_menu_item + '</a>');
            jQuery('#' + this.gopt_id).setValue(this.goptions + this.has_dropdown_style);
            this.mark_changed();
        }
        else {
            jQuery('#' + this.dd_menu_item_id).set_contents('<a href="#">' + this.dropdown_menu_item + '</a>');
            jQuery('#' + this.gopt_id).setValue(this.goptions - this.has_dropdown_style);
            this.mark_changed();
        }
        this.goptions = jQuery('#' + this.gopt_id).getIntValue();
        return;
    },

    /** Toggles the checkmark on the nostyle menu item
    **/
    toggle_nostyle: function() {
        if( !(this.goptions & this.has_nostyle) ) {
            jQuery('#' + this.nostyle_menu_item_id).set_contents('&radic; ' + '<a href="#">' + this.nostyle_menu_item + '</a>');
            jQuery('#' + this.gopt_id).setValue(this.goptions + this.has_nostyle);
            this.mark_changed();
        }
        else {
            jQuery('#' + this.nostyle_menu_item_id).set_contents('<a href="#">' + this.nostyle_menu_item + '</a>');
            jQuery('#' + this.gopt_id).setValue(this.goptions - this.has_nostyle);
            this.mark_changed();
        }
        this.goptions = jQuery('#' + this.gopt_id).getIntValue();
        return;
    },

    toggle_options_menu: function() {
        if( jQuery('#' + this.options_menu_id).isVisible() ) {
            close_window(this.options_menu_id);
        }
        else {
            open_window(this.options_menu_id);
        }
        return;
    },

    /** Open delete controls
    **/
    show_delete_controls: function() {
        this.rename_controls(_close);
        this.delete_controls(_open);
        return;
    },

    /** Open rename controls
    **/
    show_rename_controls: function() {
        this.delete_controls(_close);
        this.rename_controls(_open);
        return;
    },

    /** Close rename and delete controls
    **/
    close_group_menus: function() {
        this.delete_controls(_close);
        this.rename_controls(_close);
        return;
    },

    /** Error messagebox management
    **/
    errbox: function(c, v) {
        if( c == _clear ) {
            jQuery('#' + this.errbox_id).text('');
        }
        else if( c == _close ) {
            this.errbox(_clear);
            if( 'none' != jQuery('#'+this.errbox_id).css('display')) {
                close_window(this.errbox_id);
            }
        }
        else if( c == _get ) {
            return( jQuery('#' + this.errbox_id).get_text());
        }
        else if( c == _set ) {
            jQuery('#' + this.errbox_id).text(v);
            if( 'none' == jQuery('#'+this.errbox_id).css('display')) {
                open_window(this.errbox_id);
            }
        }
        return null;
    },

    /** System error messagebox management
    **/
    syserr: function(c, v) {
        if( c == _clear ) {
            jQuery('#' + syserrmsg_id).text('');
        }
        else if( c == _close ) {
            this.syserr(_clear);
            if( 'none' != jQuery('#'+syserrmsg_id).css('display')) {
                close_window(syserrmsg_id);
            }
        }
        else if( c == _get ) {
            return( jQuery('#' + syserrmsg_id).get_text());
        }
        else if( c == _set ) {
            jQuery('#' + syserrmsg_id).text(v);
            if( 'none' == jQuery('#'+syserrmsg_id).css('display')) {
                open_window(syserrmsg_id);
            }
        }
        return null;
    },

    /** Group name textbox management
    **/
    group_textbox: function(c, v) {
        if( c == _get ) {
            return(jQuery('#' + this.grouptbx_id).getValue());
        }
        else if( c == _set ) {
            jQuery('#' + this.grouptbx_id).setValue(v);
        }
        else if( c == _reset ) {
            jQuery('#' + this.grouptbx_id).removeClass(css_errorbox);
        }
        else if( c == _error ) {
            jQuery('#' + this.grouptbx_id).setValue(v);
            jQuery('#' + this.grouptbx_id).addClass(css_errorbox);
        }
        return null;
    },

    /** Group name textbox management
    **/
    sys_textbox: function(c, v) {
        if( c == _get ) {
            return(jQuery('#' + this.id_sys_textbox).getValue());
        }
        else if( c == _set ) {
            jQuery('#' + this.id_sys_textbox).setValue(v);
        }
        else if( c == _reset ) {
            jQuery('#' + this.id_sys_textbox).removeClass(css_errorbox);
        }
        else if( c == _error ) {
            jQuery('#' + this.id_sys_textbox).setValue(v);
            jQuery('#' + this.id_sys_textbox).addClass(css_errorbox);
        }
        return null;
    },

    /** Checks for the existance of this container in the DOM
    **/
    isDuplicateGroupName: function(name) {
        var el = 0;

        if( name.length > 0 ) {
            el = jQuery('#' + name + sfx_nav_group_container).isPresent();
        }
        return( el );
    },

    /** Sets the group color scheme and adds the dropzone class
    **/
    set_scheme: function() {
        var x = jQuery('#' + this.id_schemez).getIntValue(); // last scheme used
        if((x+1) > max_schemes) {
            x = 1;
        }
        else {
            x++;
        }
        jQuery('#' + this.id_schemez).setValue(x);
        this.scheme = this.css_group_scheme + x;
        jQuery('#' + this.root).addClass(this.scheme + ' ' + this.css_new_nav_group);
        jQuery('#' + this.container_id).addClass(css_nav_group_dropzone);
        return;
    },

    /** Adds changebars to group container
    **/
    mark_changed: function() {
        jQuery('#' + this.root).addClass(css_changebars);
        return;
    },

    /** Expands all navigation items
    **/
    open_all: function() {
        var navitems = this.get_group_items();
        navitems.each( function() {
            var nav_item = new NavItem(this.id);
            nav_item.optionbox(_open);
        });
        return;
    },

    /** Closes all navigation items
    **/
    close_all: function() {
        var navitems = this.get_group_items();
        navitems.each( function() {
            var nav_item = new NavItem(this.id);
            nav_item.optionbox(_close);
        });
        return;
    },

    restore_hidden: function() {
        var navitems = this.get_group_items();
        navitems.each( function() {
            var nav_item = new NavItem(this.id);
            nav_item.restore_hidden();
        });
    },

    /** Returns an array containing the navigation items assigned to this group
    **/
    get_group_items: function() {
        var ele = jQuery('#' + this.container_id);
        return(jQuery('.' + css_nav_item, ele));
    },

    begin_xml: function() {
        return('<navgroup name="' + this.root + '" options="' + this.goptions + '">');
    },

    end_xml: function() {
        return('</navgroup>');
    },

    /**
    ** temporarily Adds/removes items from the unassigned group
    ** for easier list viewing
    **/
    filter: function(item_filter) {

        switch( item_filter ) {
            case view_all: {
                this.filter_items(_show, css_page_item);
                this.filter_items(_show, css_cat_item);
                this.filter_items(_show, css_user_item);
                this.filter_items(_show, css_elink_item);
                this.filter_items(_show, css_llink_item);
                this.filter_items(_hide, css_noshow);
                break;
            }
            case view_pages: {
                this.filter_items(_hide, css_cat_item);
                this.filter_items(_hide, css_user_item);
                this.filter_items(_hide, css_elink_item);
                this.filter_items(_hide, css_llink_item);
                this.filter_items(_hide, css_noshow);
                this.filter_items(_show, css_page_item);
                break;
            }
            case view_pages_cats: {
                this.filter_items(_hide, css_user_item);
                this.filter_items(_hide, css_elink_item);
                this.filter_items(_hide, css_llink_item);
                this.filter_items(_hide, css_noshow);
                this.filter_items(_show, css_page_item);
                this.filter_items(_show, css_cat_item);
                break;
            }
            case view_cats: {
                this.filter_items(_hide, css_page_item);
                this.filter_items(_hide, css_user_item);
                this.filter_items(_hide, css_elink_item);
                this.filter_items(_hide, css_llink_item);
                this.filter_items(_hide, css_noshow);
                this.filter_items(_show, css_cat_item);
                break;
            }
            case view_users: {
                this.filter_items(_hide, css_page_item);
                this.filter_items(_hide, css_cat_item);
                this.filter_items(_hide, css_elink_item);
                this.filter_items(_hide, css_llink_item);
                this.filter_items(_hide, css_noshow);
                this.filter_items(_show, css_user_item);
                break;
            }
            case view_links: {
                this.filter_items(_hide, css_page_item);
                this.filter_items(_hide, css_cat_item);
                this.filter_items(_hide, css_user_item);
                this.filter_items(_hide, css_noshow);
                this.filter_items(_show, css_elink_item);
                this.filter_items(_show, css_llink_item);
                break;
            }
            case view_hidden: {
                this.filter_items(_hide, css_elink_item);
                this.filter_items(_hide, css_llink_item);
                this.filter_items(_hide, css_page_item);
                this.filter_items(_hide, css_cat_item);
                this.filter_items(_hide, css_user_item);
                this.filter_items(_show, css_noshow); // do this one last
                break;
            }
            default: { break; }
        }
        return;
    },

    /** show/hide items
    **/
    filter_items: function(c, css_item) {
        jQuery('#' + this.container_id + ' .'+ css_item).
        each(function() {
            if((c == _show) && (css_item == css_noshow))  {
                jQuery(this).fadeIn();
            }
            else if( c == _show ) {
                if( !jQuery(this).hasClass(css_noshow) ) {
                    jQuery(this).fadeIn();
                }
            }
            else if( c == _hide ) {
                jQuery(this).fadeOut();
            }
        });

        return;
    },

    iambusy: function() {
        jQuery('#' + this.root + '_busy').show();
    },

    iamnotbusy: function() {
        jQuery('#' + this.root + '_busy').hide();
    }

}; // end NavGroup class


// -------------------------------------------------------------------------
// NavItem Class
// Manages a navigation item
//
// @since 95.30
// -------------------------------------------------------------------------
NavItem.prototype = {

    initialize: function( name ) {

        // php constants
        this.sfx_nav_item_name = '_optbox';
        this.sfx_nav_item_controls = '_imenu';
        this.sfx_nav_item = '_mi';
        this.sfx_nav_item_alias_tbx = '_rtbx';
        this.sfx_item_extlink_tbx = '_utbx';
        this.sfx_item_redir_tbx = '_rdirtbx';
        this.sfx_item_ava_tbx = '_atbx';
        this.sfx_imgclass_tbx = '_itbx';
        this.sfx_item_name = '_nme';
        this.sfx_item_title = '_ttl';
        this.sfx_item_ext = '_ext';
        this.sfx_item_lvl = '_lvl';
        this.sfx_item_ex2 = '_ex2';
        this.sfx_item_options = '_opt';
        this.sfx_icon_id = '_ik';
        this.css_boxopen = 'box-open';
        this.sfx_url_window_opt = '_win';
        this.sfx_url_follow_opt = '_fol';
        this.sfx_avatar_img = '_avt';
        this.sfx_avatar_list = '_avtlist';
        this.typ_key = 'typ';
        this.idn_key = 'idn';
        this.ttl_key = 'ttl';
        this.nme_key = 'nme';
        this.opt_key = 'opt';
        this.ext_key = 'ext';
        this.lvl_key = 'lvl';
        this.ex2_key = 'ex2';
        this.set_to_do_not_use = 0;

        if(name && !name.isEmpty()) {
            this.id = name;
            this.set_rootname();
            this.set_ids();
        }
        return;
    },

    /** Take apart the components of the name
    **/
    set_rootname: function() {
        var tmp = new String(this.id);  // aN-NN-groupname_sfx
        var n = tmp.split(name_delimiter);
        this.root = n[0]; // aN-NN-groupname
        n = this.root.split(field_separator);
        this.type = n[0].charAt(1); // aN
        this.idn = n[1]; // NN
        this.groupname = n[2]; // groupname
        return;
    },

    /** Sets various DOM ids used by this class
    **/
    set_ids: function() {
        this.template_id = this.template + this.sfx_nav_item;
        this.container_id = this.root + this.sfx_nav_item;
        this.optionbox_id = this.root + this.sfx_nav_item_controls;
        this.nav_item_name_id = this.root + this.sfx_nav_item_name;
        this.alias_textbox_id = this.root + this.sfx_nav_item_alias_tbx;
        this.errbox_id = this.root + sfx_errmsg;
        this.ttl_id = this.root + this.sfx_item_title;
        this.opt_id = this.root + this.sfx_item_options;
        this.nme_id = this.root + this.sfx_item_name;
        this.ext_id = this.root + this.sfx_item_ext;
        this.lvl_id = this.root + this.sfx_item_lvl;
        this.ex2_id = this.root + this.sfx_item_ex2;
        this.urlbox_id = this.root + this.sfx_item_extlink_tbx;
        this.redirbox_id = this.root + this.sfx_item_redir_tbx;
        this.imgclass_id = this.root + this.sfx_imgclass_tbx;
        this.avabox_id = this.root + this.sfx_item_ava_tbx;
        this.avabox_id_label = this.root + this.sfx_item_ava_tbx + '_lbl';
        this.divider_dropdown_id = this.root + sfx_dropdown;
        this.icon_id = this.root + this.sfx_icon_id;
        this.sfx_url_window_opt_select_id = this.root + this.sfx_url_window_opt;
        this.sfx_url_follow_opt_select_id = this.root + this.sfx_url_follow_opt;
        this.avatar_select_id = this.root + this.sfx_avatar_list;

        if( jQuery('#' + this.container_id).isPresent() ) {
            this.item_ttl(_get);
            this.item_nme(_get);
            this.item_opt(_get);
            this.item_ext(_get);
            this.item_lvl(_get);
            this.item_ex2(_get);
        }
        return;
    },

    /** Create a new item and setup group membership
    **/
    add_item: function(nav_group, item_type) {
        this.type = item_type;
        this.group = nav_group;
        this.make_name();
        var template_root = this.template_id.split(/_/);
        var oldname = template_root[0];
        var newname = this.root;
        var clone = jQuery('#' + this.template_id).clone(true).each(function() {renameElement(this, oldname, newname);});

        clone.id = this.container_id;
        this.group.insert_navitem(clone);
        jQuery('#' + this.container_id).removeClass(css_nav_item_tplt);
        jQuery('#' + this.container_id).addClass(css_nav_item);

        // initially hides the indent/outdent controls...
        jQuery('#' +  this.container_id + '_inot').addClass('cant-see-me');
        rQ.set_callback(createSortables);
        //rQ.set_callback(removeCantSeeMe, this.container_id +'_inot');
        open_window(this.container_id, execute_callbacks);
        return;
    },

    /** Creates the DOM id for a new item
    **/
    make_name: function() {
        var d = new Date();
        var the_time = new String(d.getTime());
        var ts = the_time.substring(the_time.length-6, the_time.length);
        this.template = ('a' + this.type + field_separator + '0' + field_separator + this.group.root); // aN-0-groupname
        this.id = ('a' + this.type + field_separator + ts + field_separator + this.group.root); // aN-timestamp-groupname
        this.set_rootname();
        this.set_ids();
        return;
    },

    /** Options box management
    **/
    optionbox: function(c) {
        if( c == _open ) {
            if( !(jQuery('#' + this.optionbox_id).isVisible()) ) {
                this.errbox(_close);
                this.divider_dropdown(_reset);
                this.alias_textbox(_init);
                this.imgclass_textbox(_init);
                jQuery('#' + this.container_id).addClass(this.css_boxopen);
                this.hierarchy_controls(_hide);
                this.set_navitem_behavior(this);
                open_window(this.optionbox_id);
            }
            else {
                //It's open so we close it - a.k.a cancel
                this.optionCancel();
                this.optionbox(_close);
            }
        }
        else if(c == _close) {
            if( jQuery('#' + this.optionbox_id).isVisible() ) {
                this.errbox(_close);
                this.divider_dropdown(_reset);
                this.alias_textbox(_init);
                this.unset_navitem_behavior();
                rQ.set_callback(showHierarchyControls, this.id);

                close_window(this.optionbox_id, execute_callbacks);
                jQuery('#' + this.container_id).removeClass(this.css_boxopen);
                if( this.set_to_do_not_use ) {
                    this.hide_item();
                }
            }
        }
        return;
    },

    /**Options ok click
    **/
    optionOk: function() {
        var options = new NavItemOptions(this);
        switch( options.update() ) {
            case _updated: {
                this.mark_changed();
                this.optionbox(_close);
                break;
            }
            case _error: {
                break;
            }

            case _close:
            default:
            this.optionbox(_close);
            break;
        }
        return;
    },

    /**Options cancel click
    **/
    optionCancel: function() {
        var options;

        if( jQuery('#' + this.container_id).hasClass(css_alias_error) ) {
            // alias is missing or malformed
            options = new NavItemOptions(this);
            options.repair_alias();
            jQuery('#' + this.container_id).removeClass(css_alias_error);
        }

        if( jQuery('#' + this.container_id).hasClass(css_plaintext_error) ) {
            // plain text is missing or malformed
            options = new NavItemOptions(this);
            options.repair_plaintext();
            jQuery('#' + this.container_id).removeClass(css_plaintext_error);
        }

        if( jQuery('#' + this.container_id).hasClass(css_extern_url_error) ) {
            // url is missing or malformed
            options = new NavItemOptions(this);
            options.repair_extern_url();
            jQuery('#' + this.container_id).removeClass(css_extern_url_error);
        }

        if( jQuery('#' + this.container_id).hasClass(css_avatar_url_error) ) {
            // url is missing or malformed
            options = new NavItemOptions(this);
            options.repair_avatar_url();
            jQuery('#' + this.container_id).removeClass(css_avatar_url_error);
        }

        if( jQuery('#' + this.container_id).hasClass(css_image_class_error) ) {
            // image class is missing or malformed
            options = new NavItemOptions(this);
            options.repair_imageclass();
            jQuery('#' + this.container_id).removeClass(css_image_class_error);
        }

        return;
    },

    /** Set noshow option
    **/
    hide_item: function() {
        close_window(this.container_id);
        jQuery('#' + this.container_id).addClass(css_noshow);
        return;
    },

    /** Unset noshow option
    **/
    show_item: function() {
        if( !(jQuery('#' + this.container_id).isVisible()) ) {
            open_window(this.container_id);
            jQuery('#' + this.container_id).removeClass(css_noshow);
        }
        else {
            jQuery('#' + this.container_id).removeClass(css_noshow);
        }
        return;
    },

    restore_hidden: function() {
        var options = new NavItemOptions(this);
        options.restore_hidden();
    },

    /**Options ok click
    **/
    optionDelete: function() {
        // item is deleted by simply changing it's class
        // it will be removed when the user applies changes
        this.optionCancel();
        rQ.set_callback(deleteNavigationItem, this.container_id);
        this.optionbox(_close);
        return;
    },

    /** Update an avatar selection
    **/
    updateAvatar: function() {
        var options = new NavItemOptions(this);
        options.changeAvatar();
    },

    /** Show avatar checkbox handler for author items
    **/
    showAvatarOption: function() {
        var options = new NavItemOptions(this);
        options.showAvatar();
    },

    /** Use default avatar checkbox handler for author items
    **/
    useDefaultAvatarOption: function() {
        var options = new NavItemOptions(this);
        options.useDefAvatar();
    },

    /** Link style change
    **/
    changeLinkStyle: function() {
        var options = new NavItemOptions(this);
        options.changeLinkStyle();
    },

    /** Hide link checkbox test
    */
    hidelink_check: function() {
        var options = new NavItemOptions(this);
        options.hidelink_check();
    },

    indent: function() {
        var level = this.item_lvl(_get);
        if( level < max_levels ) {
            jQuery('#' + this.container_id).removeClass(css_level + level);

            level += 1;
            this.item_lvl(_set, level);

            jQuery('#' + this.container_id).addClass(css_level + level);
            this.mark_changed();
        }
    },

    /** Decrements the item's hierarchy level by 1
    */
    outdent: function() {
        var level = this.item_lvl(_get);
        if( level > 0 ) {
            jQuery('#' + this.container_id).removeClass(css_level + level);

            level -= 1;
            this.item_lvl(_set, level);

            jQuery('#' + this.container_id).addClass(css_level + level);
            this.mark_changed();
        }
    },

    /**  Hides/Shows the hierarchy controls and sets/resets the class
    **/
    hierarchy_controls: function(c) {
        var level;

        if( c == _hide )  {
            level = this.item_lvl(_get);
            jQuery('#' + this.root + '_inot').fadeOut('slow');
            jQuery('#' + this.container_id).removeClass(css_level + level);
        }
        else if( c == _show ) {
            level = this.item_lvl(_get);
            jQuery('#' + this.root + '_inot').fadeIn('slow');
            jQuery('#' + this.container_id).addClass(css_level + level);
        }
    },

    /** Item alias textbox management
    **/
    alias_textbox: function(c, v) {
        var alias;

        if( c == _get ) {
            var t = jQuery('#' + this.alias_textbox_id).getValue();
            return(t.clean());
        }
        else if( c == _set ) {
            alias = new String(v);
            alias = alias.clean();
            jQuery('#' + this.alias_textbox_id).setValue(alias);
            var trunc_alias = alias.truncate(15);
            var el = jQuery('#' + this.nav_item_name_id);
            el[0].innerHTML = trunc_alias;
            jQuery('#' + this.nav_item_name_id).attr("title", alias);
        }
        else if( c == _init ) {
            this.alias_textbox(_reset);
            alias = (v) ? v : this.item_nme(_get);
            this.alias_textbox(_set, alias);
        }
        else if( c == _error ) {
            jQuery('#' + this.alias_textbox_id).setValue(v);
            jQuery('#' + this.alias_textbox_id).addClass(css_errorbox);
        }
        else if( c == _reset ) {
            jQuery('#' + this.alias_textbox_id).removeClass(css_errorbox);
        }
        else if( c == _focus ) {
            jQuery('#' + this.alias_textbox_id).setFocus();
        }
        else if( c == _cksize ) {
            ;//not now
        }
        else if( c == _enable ) {
            jQuery('#' + this.alias_textbox_id).css({color: '#000'}).enableIt();
            jQuery('#' + this.alias_textbox_id).removeClass(css_disabled);
        }
        else if( c == _disable ) {
            jQuery('#' + this.alias_textbox_id).css({color: '#888'}).disableIt();
            jQuery('#' + this.alias_textbox_id).addClass(css_disabled);
        }

        return null;
    },

    /** Item image class textbox management
    **/
    imgclass_textbox: function(c, v) {
        if( jQuery('#' + this.imgclass_id).isPresent() ) {
            if( c == _get ) {
                var t = jQuery('#' + this.imgclass_id).getValue();
                t = t.clean();
                return(t.uscore());
            }
            else if( c == _set ) {
                var css_class = v.clean();
                css_class = css_class.uscore();
                jQuery('#' +  this.imgclass_id).setValue(css_class);
                this.item_ext(_set, css_class);
            }
            else if( c == _init ) {
                this.imgclass_textbox(_reset);
                var iclass = (v) ? v : this.item_ext(_get);
                this.imgclass_textbox(_set, iclass);
            }
            else if( c == _error ) {
                jQuery('#' + this.imgclass_id).setValue(v);
                jQuery('#' + this.imgclass_id).addClass(css_errorbox);
            }
            else if( c == _reset ) {
                jQuery('#' + this.imgclass_id).removeClass(css_errorbox);
            }
            else if( c == _enable ) {
                jQuery('#' + this.imgclass_id).enableIt();
                jQuery('#' + this.imgclass_id + '_lbl').removeClass(css_disabled);
                jQuery('#' + this.imgclass_id).css({color: '#000'}).enableIt();
            }
            else if( c == _disable ) {
                jQuery('#' + this.imgclass_id + '_lbl').addClass(css_disabled);
                jQuery('#' + this.imgclass_id).flush().disableIt();
                jQuery('#' + this.imgclass_id).css({color: '#888'}).disableIt();
                this.imgclass_textbox(_set, '');
            }
        }
        return null;
    },

    /** divider dropdown management
    **/
    divider_dropdown: function(c, optindex) {
        if( jQuery('#' + this.divider_dropdown_id).isPresent() ) {
            if( c == _get ) {
                var v = jQuery('#' + this.divider_dropdown_id).getSelected();
                return( parseInt(v, 10));
            }
            else if( c == _set ) {
                jQuery('#' + this.divider_dropdown_id).setSelected(optindex);
            }
            else if( c == _init ) {
                this.divider_dropdown(_reset);
                if(optindex) this.divider_dropdown(_set, optindex);
            }
            else if( c == _error ) {
                jQuery('#' + this.divider_dropdown_id).addClass(css_errorbox);
            }
            else if( c == _reset ) {
                jQuery('#' + this.divider_dropdown_id).removeClass(css_errorbox);
            }
        }
        return null;
    },

    /** Change in the divider type selection
    **/
    divider_change: function() {
        var options = new NavItemOptions(this);
        options.divider_check();
    },

    /** TODO: combine item url and avatar url boxes?
    **/

    /** Item url textbox management
    **/
    url_textbox: function(c, v) {
        if( jQuery('#' + this.urlbox_id).isPresent() ) {
            if( c == _get ) {
                var t = jQuery('#' + this.urlbox_id).getValue();
                return(t.cleanUrl());
            }
            else if( c == _set ) {
                jQuery('#' + this.urlbox_id).setValue(v);
            }
            else if( c == _error ) {
                jQuery('#' + this.urlbox_id).setValue(v);
                jQuery('#' + this.urlbox_id).addClass(css_errorbox);
            }
            else if( c == _reset ) {
                jQuery('#' + this.urlbox_id).removeClass(css_errorbox);
            }
        }
        return null;
    },

    /** redirect textbox management
    **/
    redir_textbox: function(c, v) {
        if( jQuery('#' + this.redirbox_id).isPresent() ) {
            if( c == _get ) {
                var t = jQuery('#' + this.redirbox_id).getValue();
                return(t.cleanUrl());
            }
            else if( c == _set ) {
                jQuery('#' + this.redirbox_id).setValue(v);
            }
            else if( c == _error ) {
                jQuery('#' + this.redirbox_id).setValue(v);
                jQuery('#' + this.redirbox_id).addClass(css_errorbox);
            }
            else if( c == _reset ) {
                jQuery('#' + this.redirbox_id).removeClass(css_errorbox);
            }
            else if( c == _enable ) {
                jQuery('#' + this.redirbox_id).enableIt();
                jQuery('#' + this.redirbox_id + '_lbl').removeClass(css_disabled);
                jQuery('#' + this.redirbox_id).css({color: '#000'}).enableIt();
            }
            else if( c == _disable ) {
                jQuery('#' + this.redirbox_id + '_lbl').addClass(css_disabled);
                jQuery('#' + this.redirbox_id).flush().disableIt();
                jQuery('#' + this.redirbox_id).css({color: '#888'}).disableIt();
                this.redir_textbox(_set, '');
            }
        }
        return null;
    },

    /** Avatar textbox management
    **/
    ava_textbox: function(c, v) {
        if( jQuery('#' + this.avabox_id).isPresent() ) {
            if( c == _get ) {
                var t = jQuery('#' + this.avabox_id).getValue();
                return(t.cleanUrl());
            }
            else if( c == _set ) {
                jQuery('#' + this.avabox_id).setValue(v);
            }
            else if( c == _error ) {
                jQuery('#' + this.avabox_id).setValue(v);
                jQuery('#' + this.avabox_id).addClass(css_errorbox);
            }
            else if( c == _reset ) {
                jQuery('#' + this.avabox_id).removeClass(css_errorbox);
            }
            else if( c == _disable ) {
                jQuery('#' + this.avabox_id).disableIt();
                jQuery('#' + this.avabox_id).addClass(css_disabled);
                jQuery('#' + this.avabox_id_label).addClass(css_disabled);

            }
            else if( c == _enable ) {
                jQuery('#' + this.avabox_id).enableIt();
                jQuery('#' + this.avabox_id).removeClass(css_disabled);
                jQuery('#' + this.avabox_id_label).removeClass(css_disabled);
            }
        }
        return null;
    },

    /** LVL management
    **/
    item_lvl: function(c, v) {
        if( c == _get ) {
            this.lvl = jQuery('#' + this.lvl_id).getIntValue();
            if( isNaN(this.lvl) ) {
                this.item_lvl(_set, '0');
            }
            return(this.lvl);
        }
        else if(c == _set) {
            this.lvl = jQuery('#' + this.lvl_id).setValue(v);
        }
        return null;
    },

    /** OPT management
    **/
    item_opt: function(c, v) {
        if( c == _get ) {
            this.opt = jQuery('#' + this.opt_id).getIntValue();
            if( isNaN(this.opt) ) {
                this.item_opt(_set, '0');
            }
            return(this.opt);
        }
        else if(c == _set) {
            this.opt = jQuery('#' + this.opt_id).setValue(v);
        }
        return null;
    },

    /** TTL management
    **/
    item_ttl: function(c, v) {
        if( c == _get ) {
            var ttl = jQuery('#' + this.ttl_id).getValue();
            this.ttl = ttl;
            return(ttl);
        }
        else if(c == _set) {
            jQuery('#' + this.ttl_id).setValue(v);
            this.ttl = v;
        }
        return null;
    },

    /** EXT management
    **/
    item_ext: function(c, v ) {

        if( c == _get ) {
            var ext = jQuery('#' + this.ext_id).getValue();
            this.ext = ext;
            return(ext);
        }
        else if(c == _set){
            jQuery('#' + this.ext_id).setValue(v);
            this.ext = v;
        }
        else if(c == _init) {
            this.item_ext(_set, this.ext);
        }

        return null;
    },

    /** NME management
    **/
    item_nme: function(c, v) {
        if( c == _get ) {
            var nme = jQuery('#' + this.nme_id).getValue();
            this.nme = nme;
            return(this.nme);
        }
        else if(c == _set) {
            jQuery('#' + this.nme_id).setValue(v);
            this.nme = v;
            this.alias_textbox(_set, this.nme);
        }
        else if(c == _init) {
            this.item_nme(_set, this.nme);
        }
        return null;
    },

    /** EX2 management
    **/
    item_ex2: function(c, v ) {
        if( c == _get ) {
            var ex2 = jQuery('#' + this.ex2_id).getValue();
            this.ex2 = ex2;
            return(this.ex2);
        }
        else if(c == _set){
            jQuery('#' + this.ex2_id).setValue(v);
            this.ex2 = v;
        }
        else if(c == _init) {
            this.item_ex2(_set, this.ex2);
        }
        return null;
    },

    /** Error messagebox management
    **/
    errbox: function(c, v) {
        if( c == _clear ) {
            jQuery('#' + this.errbox_id).clear();
        }
        else if( c == _close ) {
            this.errbox(_clear);
            if(jQuery('#' + this.errbox_id).isVisible()) close_window(this.errbox_id);
        }
        else if( c == _get ) {
            return( jQuery('#' + this.errbox_id) ).getValue();
        }
        else if( c == _set ) {
            jQuery('#' + this.errbox_id).setContents(v);
            if(!(jQuery('#' + this.errbox_id).isVisible())) open_window(this.errbox_id);
        }
        return null;
    },

    /** Adds changebars to this item
    **/
    mark_changed: function() {
        jQuery('#' + this.container_id).addClass(css_changebars);
        return;
    },

    /** Set up click event handlers for this navigation item
    ** only when the options are visible
    **/
    set_navitem_behavior: function() {

        if( this.type == item_is_divider ) {
            // Divider type selections
            jQuery('#' + this.optionbox_id + ' .divider_selection').click(function() {
                var nav_item = new NavItem(this.id);
                nav_item.divider_change();
                return true;
            });
        }

        if( this.type == item_is_author ) {
            // checkbox for using an avatar
            jQuery('#' + this.optionbox_id + ' .showavatar').click(function() {
                var nav_item = new NavItem(this.id);
                nav_item.showAvatarOption();
                return true;
            });

            // Avatar selection dropdown box
            jQuery('#' + this.optionbox_id + ' .avselect').click(function() {
                var nav_item = new NavItem(this.id);
                nav_item.updateAvatar();
                return false;
            });

            // checkbox for using the default avatar
            jQuery('#' + this.optionbox_id + ' .usedefavatar').click(function() {
                var nav_item = new NavItem(this.id);
                nav_item.useDefaultAvatarOption();
                return true;
            });
        }

        // checkbox for hiding link text
        jQuery('#' + this.optionbox_id + ' .hidelink').click(function() {
            var nav_item = new NavItem(this.id);
            nav_item.hidelink_check();
            return true;
        });

        // link display style dropdown box
        jQuery('#' + this.optionbox_id + ' .ancselect').click(function() {
            var nav_item = new NavItem(this.id);
            nav_item.changeLinkStyle();
            return false;
        });

        if( this.type == item_is_link ) {

            jQuery('#' + this.root + '_cb1').click(function() {
                // create login form checked/unchecked
                var nav_item = new NavItem(this.id);
                var nav_options = new NavItemOptions(nav_item);
                nav_options.use_login_form();
                return true;
            });

            jQuery('#' + this.root + '_cb2').click(function() {
                // redirect to referring page checked/unchecked
                var nav_item = new NavItem(this.id);
                var nav_options = new NavItemOptions(nav_item);
                nav_options.redirect_refer();
                return true;
            });

            jQuery('#' + this.root + '_cb3').click(function() {
                // redirect to user defined url checked/unchecked
                var nav_item = new NavItem(this.id);
                var nav_options = new NavItemOptions(nav_item);
                nav_options.redirect_user_url();
                return true;
            });
        }
    },

    /** Teardown click event handlers for this navigation item
    ** only when the options are not visible
    **/
    unset_navitem_behavior: function() {

        if( this.type == item_is_divider ) {
            jQuery('#' + this.optionbox_id + ' .divider_selection').unbind();
        }

        if( this.type == item_is_author ) {
            jQuery('#' + this.optionbox_id + ' .avselect').unbind();
            jQuery('#' + this.optionbox_id + ' .showavatar').unbind();
            jQuery('#' + this.optionbox_id + ' .usedefavatar').unbind();
        }

        if( this.type == item_is_link ) {
            jQuery('#' + this.optionbox_id + this.sfx_item_cb2).unbind();
            jQuery('#' + this.optionbox_id + this.sfx_item_cb3).unbind();
        }

        jQuery('#' + this.optionbox_id + ' .ancselect').unbind();
        jQuery('#' + this.optionbox_id + ' .hidelink').unbind();
    },

    /** Outputs the xml data for this item
    **/
    get_xmldata: function(group) {

        var xml = '';

        if( jQuery('#' + this.container_id).hasClass(css_deleted) ) {
            ;// skip deleted items
        }
        else if( ((this.groupname == id_default_group) && (this.type == item_is_divider)) ) {
            ;// skip dividers in the unassigned group
        }
        else {
            xml =
            '<' + 'item>' +
            this.set_xml_attr(this.typ_key, this.type, 0) +
            this.set_xml_attr(this.idn_key, this.idn,  0) +
            this.set_xml_attr(this.ttl_key, this.ttl,  1) +
            this.set_xml_attr(this.nme_key, this.nme,  1) +
            this.set_xml_attr(this.opt_key, this.opt,  0) +
            this.set_xml_attr(this.ext_key, this.ext,  1) +
            this.set_xml_attr(this.lvl_key, this.lvl,  0) +
            this.set_xml_attr(this.ex2_key, this.ex2,  1) +
            '<' + '/item>';
        }
        return(xml);
    },

    /** returns an xml line to be added to the output
    ** strings are encapsulated within CDATA and encoded
    ** to prevent them from being mistaken for $_POST variables
    **/
    set_xml_attr: function(key, v, encode) {

        var val = new String(v);
        val = val.replace(new RegExp("&", "gi"), "#amp;"); // replace & with #amp;
        var r = '<' + key;

        if( val.isEmpty() ) {
            r += '/>'; // empty
        }
        else {

            if( encode ) {
                r += '><![CDATA[' +  val + ']]>';
            }
            else {
                r += '>' + val;
            }
            r += '</' + key + '>';
        }

        return(r);
    }

}; // end NavItem class

// -------------------------------------------------------------------------
// NavItemOption Class
// Manages a navigation item options
//
// @since 95.30
// -------------------------------------------------------------------------
NavItemOptions.prototype = {

    initialize: function( navitem ) {

        // php constants
        this.sfx_item_cb1 = '_cb1';
        this.sfx_item_cb2 = '_cb2';
        this.sfx_item_cb3 = '_cb3';
        this.sfx_item_cb4 = '_cb4';
        this.sfx_item_cb5 = '_cb5';
        this.sfx_item_cb7 = '_cb7';
        this.sfx_item_cb8 = '_cb8';
        this.sfx_item_cb9 = '_cb9';
        this.sfx_item_cb10 = '_cb10';
        this.sfx_item_cb11 = '_cb11';
        this.sfx_item_cb13 = '_cb13';
        this.sfx_anchor_opts = '_ao';

        this.def_hrule_text = 'Horiz Rule';
        this.def_divider_text = 'Empty Space';
        this.def_plain_text = 'Plain Text';
        this.show_in_list = 1;
        this.append_post_count = 2;
        this.show_if_empty = 4;
        this.usedesc = 8;

        this.no_link_text = 128;
        this.isprivate = 16;
        this.isdraftpage = 1;
        this.empty_space_divider = 0;
        this.hrule_divider = 1;
        this.plain_text_divider =  2;
        this.follow_link = 1;
        this.nofollow_link = 4096;
        this.opens_same_window = 2;
        this.do_not_display = 512;
        this.divmask = 3;
        this.css_private = 'private';

        this.use_avatar = 1;
        this.use_def_avatar = 8;
        //--> ? this.avatar_path = 'AVPATH';
        this.include_email = 1024;
        this.include_website = 64;
        this.include_bio = 256;

        this.text_over_graphic = 64;
        this.text_with_side_graphic = 256;
        this.isgraphic = 128;
        this.no_link_text = 128;
        this.make_login_form = 1;
        this.use_referrer = 2;
        this.use_redirect_url = 4;

        this.url_prompt = ":: Your URI? ::";
        this.plain_text_prompt = ":: Missing text - try again ::";
        this.missing_text_prompt = ":: Missing text - try again ::";
        this.bad_alias_prompt = ":: Invalid alias - try again ::";
        this.invalid_text_prompt = ":: Invalid text - try again ::";
        this.class_prompt = ":: CSS class is missing ::";
        this.divider_type0 = 'Empty Space';
        this.divider_type1 = 'Horizontal Rule';

        this.navitem = navitem;
        this.container_id = this.navitem.container_id;

        this.marked_nofollow = jQuery('#' + this.navitem.root + this.sfx_item_cb13).isPresent() ?
        (jQuery('#' + this.navitem.root + this.sfx_item_cb13).isChecked() ? this.nofollow_link : 0) : 0;

        this.marked_private = jQuery('#' + this.navitem.root + this.sfx_item_cb5).isPresent() ?
        (jQuery('#' + this.navitem.root + this.sfx_item_cb5).isChecked() ? this.isprivate : 0) : 0;

        this.hide_link_text = jQuery('#' + this.navitem.root + this.sfx_item_cb8).isPresent() ?
        (jQuery('#' + this.navitem.root + this.sfx_item_cb8).isChecked() ? this.no_link_text: 0) : 0;

        this.do_not_use = jQuery('#' + this.navitem.root + this.sfx_item_cb10).isPresent() ?
        (jQuery('#' + this.navitem.root + this.sfx_item_cb10).isChecked() ? this.do_not_display: 0) : 0;

        this.link_as = 0;
        if( jQuery('#' + this.navitem.root + this.sfx_anchor_opts).isPresent()) {
            var opts = jQuery('#' + this.navitem.root + this.sfx_anchor_opts).getSelected();
            this.link_as = parseInt(opts, 10);
            if( (this.link_as == this.text_with_side_graphic) ) {
                this.navitem.imgclass_textbox(_enable);
            }
            else if( this.link_as == this.isgraphic ) {
                this.hide_link_text = this.no_link_text;
            }
        }

        return;
    },

    /** update options for navigation items
    **/
    update: function() {

        if( this.navitem.opt == undefined ) this.navitem.item_opt(_get);
        if( this.navitem.ext == undefined ) this.navitem.item_ext(_get);

        var rc = _close;
        this.navitem.alias_textbox(_reset);
        if( this.navitem.type != item_is_divider ) {
            rc = this.check_alias(_close);
        }
        if( rc != _error ) {
            switch( this.navitem.type ) {
                case item_is_category: { rc = this.category_options(rc); break; }
                case item_is_divider: {  rc = this.divider_options(rc);  break; }
                case item_is_elink: {    rc = this.elink_options(rc);    break; }
                case item_is_page: {     rc = this.page_options(rc);     break; }
                case item_is_link: {     rc = this.link_options(rc);     break; }
                case item_is_author: {   rc = this.author_options(rc);   break; }
                default: { break; }
            }
            if( rc != _error ) {
                this.private_check();
            }
            if( rc != _error ) {
                this.do_not_use_check();
            }
        }
        return(rc);
    },

    /** Makes this item visible if it is currently hidden
    **/
    restore_hidden: function() {

        if(this.do_not_use !== 0) {
            jQuery('#' + this.navitem.root + this.sfx_item_cb10).unCheckIt();
            jQuery('#' + this.navitem.container_id).removeClass(css_noshow);
            var new_opts = (this.navitem.opt - this.do_not_use);
            this.navitem.item_opt(_set, new_opts);
            this.mark_changed();
            open_window(this.navitem.container_id);
        }
        return;
    },

    /** Adjust settings for hiding link text
    **/
    hidelink_check: function() {

        if( this.navitem.type == item_is_category || this.navitem.type == item_is_author ) {

            if( this.hide_link_text ) {
                jQuery('#' + this.navitem.root + this.sfx_item_cb2).unCheckIt().disableIt();
                jQuery('#' + this.navitem.root + this.sfx_item_cb2 + '_lbl').addClass(css_disabled);

                if( this.navitem.type == item_is_author ) {
                    jQuery('#' + this.navitem.root + this.sfx_item_cb11).unCheckIt().disableIt();
                    jQuery('#' + this.navitem.root + this.sfx_item_cb11 + '_lbl').addClass(css_disabled);
                    jQuery('#' + this.navitem.root + this.sfx_item_cb7).unCheckIt().disableIt();
                    jQuery('#' + this.navitem.root + this.sfx_item_cb7 + '_lbl').addClass(css_disabled);
                    jQuery('#' + this.navitem.root + this.sfx_item_cb9).unCheckIt().disableIt();
                    jQuery('#' + this.navitem.root + this.sfx_item_cb9 + '_lbl').addClass(css_disabled);
                }
            }
            else {
                jQuery('#' + this.navitem.root + this.sfx_item_cb2).enableIt();
                jQuery('#' + this.navitem.root + this.sfx_item_cb2 + '_lbl').removeClass(css_disabled);

                if(this.navitem.type == item_is_author) {
                    jQuery('#' + this.navitem.root + this.sfx_item_cb11).enableIt();
                    jQuery('#' + this.navitem.root + this.sfx_item_cb11 + '_lbl').removeClass(css_disabled);
                    jQuery('#' + this.navitem.root + this.sfx_item_cb7).enableIt();
                    jQuery('#' + this.navitem.root + this.sfx_item_cb7 + '_lbl').removeClass(css_disabled);
                    jQuery('#' + this.navitem.root + this.sfx_item_cb9).enableIt();
                    jQuery('#' + this.navitem.root + this.sfx_item_cb9 + '_lbl').removeClass(css_disabled);
                }
            }
        }
        return;
    },

    /** Check for changes in the alias text box
    **/
    check_alias: function(rc) {

        var new_alias = this.navitem.alias_textbox(_get);

        if( new_alias.isEmpty() ) {
            this.navitem.alias_textbox(_set, this.navitem.item_ttl(_get));
            this.navitem.item_nme(_set, this.navitem.item_ttl(_get));
        }
        else if(new_alias.isSameAs(this.missing_text_prompt) ||
        new_alias.isSameAs(this.invalid_text_prompt) ||
        new_alias.isSameAs(this.plain_text_prompt)) {
            rc = _error;
            this.navitem.alias_textbox(_error, this.bad_alias_prompt);
            this.addError(css_alias_error);
        }
        else if( (this.navitem.nme != new_alias) ) {
            this.navitem.alias_textbox(_set, new_alias);
            this.navitem.item_nme(_set, new_alias);
            rc = _updated;
        }
        return(rc);
    },

    /** Handles category options
    **/
    category_options: function(rc) {

        var include_cat  = jQuery('#' + this.navitem.root + this.sfx_item_cb1).isChecked() ? this.show_in_list: 0;
        var append_posts = jQuery('#' + this.navitem.root + this.sfx_item_cb2).isChecked() ? this.append_post_count: 0;
        var show_empty_cat = jQuery('#' + this.navitem.root + this.sfx_item_cb3).isChecked() ? this.show_if_empty: 0;
        var usedesc = jQuery('#' + this.navitem.root + this.sfx_item_cb4).isChecked() ? this.usedesc: 0;
        var new_opts = include_cat + append_posts + show_empty_cat + usedesc + this.marked_private +
        this.link_as + this.do_not_use + this.marked_nofollow;
        rc = this.check_imageclass(rc);

        if( (rc != _error) && (new_opts != this.navitem.opt) ) {
            this.navitem.item_opt(_set, new_opts);
            rc = _updated;
        }
        return(rc);
    },

    /** Handles divider options
    **/
    divider_options: function(rc) {

        this.navitem.alias_textbox(_reset);
        this.navitem.divider_dropdown(_reset);
        var new_divtype = dd_option = this.navitem.divider_dropdown(_get);
        var new_opts = dd_option + this.marked_private + this.marked_nofollow;
        var cur_divtype = (this.navitem.opt & this.divmask);
        var fallback_divtype = cur_divtype;

        if( cur_divtype != new_divtype ) {
            if( new_divtype == this.empty_space_divider ) {
                this.navitem.item_nme(_set, this.def_divider_text);
                cur_divtype = new_divtype;
                rc = _updated;
            }
            else if( new_divtype == this.hrule_divider ) {
                this.navitem.item_nme(_set, this.def_hrule_text);
                cur_divtype = new_divtype;
                rc = _updated;
            }
            else {
                cur_divtype = new_divtype;
                rc = _updated;
            }
        }

        if( cur_divtype == this.plain_text_divider ) {
            var plain_text = this.navitem.alias_textbox(_get);

            if(plain_text.isEmpty()) {
                this.navitem.alias_textbox(_error, this.missing_text_prompt);
                this.addError(css_plaintext_error);
                rc = _error;
            }
            else {
                if( !plain_text.isSameAs(this.def_hrule_text) && !plain_text.isSameAs(this.def_divider_text) &&
                !plain_text.isSameAs(this.missing_text_prompt) && !plain_text.isSameAs(this.plain_text_prompt) ) {
                    this.navitem.item_nme(_set, plain_text);
                }
                else {
                    this.navitem.alias_textbox(_error, this.plain_text_prompt);
                    this.addError(css_plaintext_error);
                    rc = _error;
                }
            }
        }

        if( rc == _error ) {
            this.navitem.divider_dropdown(_set, fallback_divtype);
            this.navitem.divider_dropdown(_error);
        }

        if( (rc != _error) && (new_opts != this.navitem.opt) ) {
            this.navitem.item_opt(_set, new_opts);
            rc = _updated;
            this.mark_changed();
        }
        return(rc);
    },

    /** Handles divider type changes
    **/
    divider_check: function() {

        var s = this.navitem.divider_dropdown(_get);

        if( s == this.empty_space_divider ) {
            this.navitem.alias_textbox(_set, this.divider_type0);
            this.navitem.alias_textbox(_disable);
        }
        else if( s == this.hrule_divider ) {
            this.navitem.alias_textbox(_set, this.divider_type1);
            this.navitem.alias_textbox(_disable);
        }
        else {
            this.navitem.alias_textbox(_set, '');
            this.navitem.alias_textbox(_enable);
            this.navitem.alias_textbox(_focus);
        }
    },

    /** Handles external link options
    **/
    elink_options: function(rc) {
        var new_url;
        var follow_opt = parseInt( jQuery('#' + this.navitem.sfx_url_follow_opt_select_id).getSelected(), 10 ); // select option
        var opens_same_window_opt = parseInt( jQuery('#' + this.navitem.sfx_url_window_opt_select_id).getSelected(), 10 ); // select option
        var new_opts = this.marked_private + this.link_as + follow_opt + opens_same_window_opt + this.do_not_use;

        // get url
        this.navitem.url_textbox(_reset);
        new_url = this.navitem.url_textbox(_get);

        if( new_url.isEmpty() || new_url.isSameAs(this.url_prompt) ) {
            this.navitem.url_textbox(_error, this.url_prompt);
            this.addError(css_extern_url_error);
            rc = _error;
        }
        else if( new_url != this.navitem.ttl ) {
            this.navitem.item_ttl(_set, new_url);
            rc = _updated;
        }

        rc = this.check_imageclass(rc);

        if( (rc != _error) && (new_opts != this.navitem.opt) ) {
            this.navitem.item_opt(_set, new_opts);
            rc = _updated;
            this.mark_changed();
        }
        return(rc);
    },

    /** Handles author options
    **/
    author_options: function(rc) {

        var show_avatar  = jQuery('#' + this.navitem.root + this.sfx_item_cb1).isChecked() ? this.use_avatar : 0;
        var use_def_avatar = jQuery('#' + this.navitem.root + this.sfx_item_cb4).isChecked() ? this.use_def_avatar : 0;
        var append_posts = jQuery('#' + this.navitem.root + this.sfx_item_cb2).isChecked() ? this.append_post_count : 0;
        var show_if_no_posts = jQuery('#' + this.navitem.root + this.sfx_item_cb3).isChecked() ? this.show_if_empty : 0;
        var avatar_to_use = jQuery('#' + this.navitem.avatar_select_id).getSelected();
        var has_email = jQuery('#' + this.navitem.root + this.sfx_item_cb11).isChecked() ? this.include_email: 0;
        var has_website = jQuery('#' + this.navitem.root + this.sfx_item_cb7).isChecked() ? this.include_website: 0;
        var has_bio = jQuery('#' + this.navitem.root + this.sfx_item_cb9).isChecked() ? this.include_bio: 0;
        var new_opts = (this.hide_link_text + show_avatar + use_def_avatar + append_posts + show_if_no_posts +
        this.do_not_use + has_email + has_bio + has_website + this.marked_nofollow);
        this.navitem.ava_textbox(_reset);

        if( show_avatar !== 0 ) {
            if( use_def_avatar === 0 ) {
                var new_ava = this.navitem.ava_textbox(_get);

                if( new_ava.isEmpty() || new_ava.isSameAs(this.url_prompt)) {
                    this.navitem.ava_textbox(_error, this.url_prompt);
                    this.addError(css_avatar_url_error);
                    rc = _error;
                }
                else if( new_ava != this.navitem.ext ) {
                    this.navitem.item_ext(_set, new_ava);
                    this.navitem.ava_textbox(_set, new_ava);
                    rc = _updated;
                }
            }
            else {
                var t = this.navitem.item_ext(_get);
                rc = ( t.isSameAs(avatar_to_use ) ) ? _updated: 0;
                this.navitem.item_ext(_set, avatar_to_use);
                if( rc == _updated ) {
                    this.mark_changed();
                }
            }
        }

        if( (rc != _error) && (new_opts != this.navitem.opt) ) {
            this.navitem.item_opt(_set, new_opts);
            rc = _updated;
            this.mark_changed();
        }
        return(rc);
    },

    /** Change the avatar graphic to one of the defaults
    **/
    changeAvatar: function() {

        var avatar_to_use = jQuery('#' + this.navitem.avatar_select_id).getSelected();
        var avatar_img = avatar_to_use;
        jQuery('#' + this.navitem.root + this.navitem.sfx_avatar_img).attr('src', avatar_img);
        this.navitem.item_ext(_set, avatar_to_use);
        this.navitem.ava_textbox(_set, '');
        return;
    },

    /** Enables/disables controls related to showing an avatar
    **/
    showAvatar: function() {

        if( jQuery('#' + this.navitem.root + this.sfx_item_cb1).isChecked() ) {
            // Show an avatar
            jQuery('#' + this.navitem.root + this.sfx_item_cb4 + '_lbl').removeClass(css_disabled); // enable 'use the default'
            jQuery('#' + this.navitem.root + this.sfx_item_cb4).enableIt();

            // allow link text to be hidden
            jQuery('#' + this.navitem.root + this.sfx_item_cb8).enableIt();
            jQuery('#' + this.navitem.root + this.sfx_item_cb8 + '_lbl').removeClass(css_disabled);

            if(jQuery('#' + this.navitem.root + this.sfx_item_cb4).isChecked()) {

                // using a default - allow link text to be hidden
                jQuery('#' + this.navitem.root + this.sfx_item_cb8 + '_lbl').removeClass(css_disabled);
                jQuery('#' + this.navitem.root + this.sfx_item_cb8).enableIt(); // allow text to be hidden

                // disable user input controls
                this.userAvatarControls(_disable);
            }
            else {
                // enable user input controls
                this.userAvatarControls(_enable);
            }
        }
        else {
            // not using an avatar - turn off all default avatar and user controls
            jQuery('#' + this.navitem.root + this.sfx_item_cb4 + '_lbl').addClass(css_disabled);
            jQuery('#' + this.navitem.root + this.sfx_item_cb4).disableIt();
            jQuery('#' + this.navitem.avatar_select_id).disableIt();
            this.navitem.ava_textbox(_disable, '');
            this.navitem.ava_textbox(_reset);

            // Can't hide the text link if not using an avatar
            jQuery('#' + this.navitem.root + this.sfx_item_cb8).unCheckIt(); // uncheck it
            jQuery('#' + this.navitem.root + this.sfx_item_cb8 + '_lbl').addClass(css_disabled);
            jQuery('#' + this.navitem.root + this.sfx_item_cb8).disableIt();
        }
        return;
    },

    /** Enables/disables controls related to using the default avatar
    **/
    useDefAvatar: function() {
        this.userAvatarControls(jQuery('#' + this.navitem.root + this.sfx_item_cb4).isChecked() ? _disable : _enable);
        return;
    },

    userAvatarControls: function( c ) {

        // disable user controls that allow avatar URL input
        // enable all 'default' oriented controls

        if( c == _disable ) {
            // initialize the controls and disable changes
            // - get the avatar selected in the select - put it into the imagebox and save it
            this.changeAvatar();

            // enable the select dropdown
            jQuery('#' +  this.navitem.avatar_select_id).ungrey().enableIt();

            // disable the input box
            this.navitem.ava_textbox(_reset);
            this.navitem.ava_textbox(_disable, '');
        }

        else if(c == _enable) {

            // disable the select dropdown
            jQuery('#' +  this.navitem.avatar_select_id).grey().disableIt();

            // enable the input controls
            this.navitem.ava_textbox(_enable);
            this.navitem.ava_textbox(_set, '');
        }
    },

    /** Handles page options
    **/
    page_options: function(rc) {

        var new_opts = this.marked_private + this.link_as + this.do_not_use + this.marked_nofollow;
        rc = this.check_imageclass(rc);

        if( (rc != _error) && (new_opts != this.navitem.opt) ) {
            this.navitem.item_opt(_set, new_opts);
            rc = _updated;
            this.mark_changed();
        }
        return(rc);
    },

    /** Handles internal link options
    **/
    link_options: function(rc) {
        var new_url;
        var new_opts = this.marked_private + this.link_as + this.do_not_use + this.marked_nofollow;
        rc = this.check_imageclass(rc);

        if( jQuery('#' + this.navitem.redirbox_id).isPresent()) {
            new_url = this.navitem.redir_textbox(_get);
            var use_login_form = jQuery('#' + this.navitem.root + this.sfx_item_cb1).isChecked() ? this.make_login_form: 0;
            var use_redirect_referrer = jQuery('#' + this.navitem.root + this.sfx_item_cb2).isChecked() ? this.use_referrer: 0;
            var use_redirect_url = jQuery('#' + this.navitem.root + this.sfx_item_cb3).isChecked() ? this.use_redirect_url: 0;
            new_opts += (use_login_form + use_redirect_url + use_redirect_referrer);

            if( use_redirect_url ) {
                this.navitem.item_ex2(_set, new_url);
            }
            else {
                this.navitem.item_ex2(_set, new_url);
            }

            new_url = this.navitem.redir_textbox(_get);
            if( new_url != this.navitem.ex2 ) {
                this.navitem.item_ex2(_set, new_url);
                rc = _updated;
                this.mark_changed();
            }
        }

        if( (rc != _error) && (new_opts != this.navitem.opt) ) {
            this.navitem.item_opt(_set, new_opts);
            rc = _updated;
            this.mark_changed();
        }
        return(rc);
    },

    /** Handle check/uncheck use login form
    **/
    use_login_form: function() {

        if( jQuery('#' + this.navitem.root + this.sfx_item_cb1).isChecked() ){
            // enable the redirect checkboxes and the redirect textbox
            jQuery('#' + this.navitem.root + this.sfx_item_cb2).enableIt().unCheckIt();
            jQuery('#' + this.navitem.root + this.sfx_item_cb2 + '_lbl').removeClass(css_disabled);
            jQuery('#' + this.navitem.root + this.sfx_item_cb3).enableIt().unCheckIt();
            jQuery('#' + this.navitem.root + this.sfx_item_cb3 + '_lbl').removeClass(css_disabled);
            this.navitem.redir_textbox(_disable);
        }
        else {
            // disabled redirect checkboxes and redirect textbox
            jQuery('#' + this.navitem.root + this.sfx_item_cb2).disableIt().unCheckIt();
            jQuery('#' + this.navitem.root + this.sfx_item_cb2 + '_lbl').addClass(css_disabled);
            jQuery('#' + this.navitem.root + this.sfx_item_cb3).disableIt().unCheckIt();
            jQuery('#' + this.navitem.root + this.sfx_item_cb3 + '_lbl').addClass(css_disabled);
            this.navitem.redir_textbox(_disable);
        }
    },

    /** Handle redirect to referring page for user login
    **/
    redirect_refer: function() {

        if( jQuery('#' + this.navitem.root + this.sfx_item_cb2).isChecked() ) {
            // disable the user defined redirect
            jQuery('#' + this.navitem.root + this.sfx_item_cb3).disableIt().unCheckIt();
            jQuery('#' + this.navitem.root + this.sfx_item_cb3 + '_lbl').addClass(css_disabled);
            this.navitem.redir_textbox(_disable);
        }
        else {
            // enable the user defined redirect
            jQuery('#' + this.navitem.root + this.sfx_item_cb3).enableIt().unCheckIt();
            jQuery('#' + this.navitem.root + this.sfx_item_cb3 + '_lbl').removeClass(css_disabled);
        }
    },

    /** Handle redirect to user url for user login
    **/
    redirect_user_url: function() {

        if( jQuery('#' + this.navitem.root + this.sfx_item_cb3).isChecked() ) {
            // enable the textbox
            this.navitem.redir_textbox(_enable);

            // disable the referrer redirect
            jQuery('#' + this.navitem.root + this.sfx_item_cb2).disableIt().unCheckIt();
            jQuery('#' + this.navitem.root + this.sfx_item_cb2 + '_lbl').addClass(css_disabled);
        }
        else {
            // disable the textbox
            this.navitem.redir_textbox(_disable);

            // enable the referrer redirect
            jQuery('#' + this.navitem.root + this.sfx_item_cb2).enableIt().unCheckIt();
            jQuery('#' + this.navitem.root + this.sfx_item_cb2 + '_lbl').removeClass(css_disabled);
        }
    },

    /** Checks privacy
    **/
    private_check: function() {

        if( this.navitem.opt & this.marked_private ) {
            jQuery('#' + this.container_id).addClass(this.css_private);
            jQuery('#' + this.navitem.icon_id).addClass(this.css_private);
        }
        else {
            jQuery('#' + this.container_id).removeClass(this.css_private);
            jQuery('#' + this.navitem.icon_id).removeClass(this.css_private);
        }
        return;
    },

    /** Checks moving the item to the hidden group
    **/
    do_not_use_check: function() {

        if( this.navitem.opt & this.do_not_use ) {
            this.navitem.set_to_do_not_use = 1;
        }
        else {
            jQuery('#' + this.navitem.container_id).removeClass(css_noshow);
        }
        return;
    },

    /** Validates image class options
    **/
    check_imageclass: function(rc) {

        var new_imgclass = this.navitem.imgclass_textbox(_get);

        if( this.link_as == this.text_with_side_graphic) {
            if( new_imgclass.isEmpty() || new_imgclass.isSameAs(this.class_prompt)) {
                this.navitem.imgclass_textbox(_error, this.class_prompt);
                this.addError(css_image_class_error);
                rc = _error;
            }
            else {
                if( (new_imgclass != this.navitem.ext) || this.navitem.ext.isEmpty() ) {
                    this.navitem.imgclass_textbox(_set, new_imgclass);
                    rc = _updated;
                    this.mark_changed();
                }
            }
        }
        else {
            // empty this
            this.navitem.imgclass_textbox(_set, '');
        }
        return(rc);
    },

    /** Link style select box changes
    **/
    changeLinkStyle: function() {
        this.navitem.imgclass_textbox(this.link_as == this.text_with_side_graphic ? _enable: _disable);
        this.hidelink_check();
        return;
    },

    /** Adds changebars to this item
    **/
    mark_changed: function() {
        jQuery('#' + this.container_id).addClass(css_changebars);
        return;
    },

    addError: function(error_class) {
        jQuery('#' + this.container_id).addClass(error_class);
        return;
    },

    /** Repairs a missing or malformed alias
    **/
    repair_alias: function() {
        //this.alias_textbox(_init);
        return;
    },

    /** Repairs a missing or malformed plaintext divider
    **/
    repair_plaintext: function() {
        return;
    },

    /** Repairs a missing or malformed external url
    **/
    repair_extern_url: function() {
        return;
    },

    /** Repairs a missing or malformed avatar url
    **/
    repair_avatar_url: function() {
        // tick the 'use default'
        jQuery('#' + this.navitem.root + this.sfx_item_cb4).checkIt();
        this.changeAvatar();
        this.author_options(0);
        return;
    },

    /** Repairs a missing or malformed imageclass
    **/
    repair_imageclass: function() {
        var new_opts = this.navitem.item_opt(_get, '');
        new_opts -= this.text_with_side_graphic;
        this.navitem.item_opt(_set, new_opts);
        this.navitem.imgclass_textbox(_set, '');
        this.navitem.imgclass_textbox(_reset);
        jQuery('#' + this.navitem.root + this.sfx_anchor_opts).setSelected('0');
        return;
    }

}; // end NavItemOptions class


// -------------------------------------------------------------------------
// Helper functions
//
// -------------------------------------------------------------------------

/**
* Opens a container
*/
function open_window(ele_id, callback) {
    jQuery('#' + ele_id).slideDown("normal", callback);
    return;
}

/**
* Closes a container
*/
function close_window(ele_id, callback) {
    jQuery('#' + ele_id).slideUp("normal", callback);
    return;
}

/** Executes a list of callback functions after a graphic
** effect has ended
**/
function execute_callbacks() {
    rQ.exec();
}

/** Deletes a group and adopts all the group items
**/
function do_adoption(id) {
    var unassigned_group = new NavGroup(id_default_group + sfx_nav_group_container);
    unassigned_group.delete_group(id);
    return;
}

/** Removes an navigation item (final step)
**/
function deleteNavigationItem(id) {
    jQuery('#' + id).remove();
    return;
}
/**
* Helper function
* Shows the < > hierarchy controls on an item
**/
function showHierarchyControls(id) {
    var navItem = new NavItem(id);
    navItem.hierarchy_controls(_show);
    return;
}

/** Helper function
** Removes cant-see-me class from something....
**/
function removeCantSeeMe(id) {
    jQuery('#' + id).hide();
    jQuery('#' + id).removeClass('cant-see-me');
    jQuery('#' + id).show('slow');
    return;
}

/**
* Helper function to recursively rename node ids/nm
**/
function renameElement(node, oldname, newname) {

    if( node.childNodes.length > 0 ) {
        for(var i = 0; i < node.childNodes.length; i++) {
            var cnode = node.childNodes[i];
            if( cnode.nodeType != 3 ) {
                renameElement(cnode, oldname, newname);
            }
        }
    }
    // name it.
    nameNode(node, oldname, newname);
}

/** Change the id and name of a node
**/
function nameNode(node, oldname, newname) {

    if( node.id && node.id.length > 0)  {
        node.id = node.id.replaceName(oldname, newname);
    }

    if( node.nm && node.nm.length > 0 ) {
        node.nm = node.nm.replaceName(oldname, newname);
    }
}

/**
* Helper function
* Set up the menu group to enable dragging
*
* @todo - convert this to something else that creates drag/drop
*/
function createSortables() {

    var zone;
    var gDropZone = document.getElementsByClassName(css_nav_group_dropzone);

    for( var x = 0; x < gDropZone.length; x++ ) {
        zone = gDropZone[x].id;

        Sortable.create($(zone), {
            format: /(.*)/,
            tag: nav_group_tag,
            dropOnEmpty: true,
            containment: gDropZone,
            constraint: false,
            only: css_nav_item,
            handle: css_item_draghandle,
            delay: 50,
            onUpdate: dropUpdate
        });
    }

    var groups =  document.getElementsByClassName(css_group_draghandle);
    if( groups.length > 0 ) {
        Sortable.create(id_page_wrapper, {
            tag: group_tags,
            constraint: false,
            only: nav_containers,
            handle: css_group_draghandle
        });
    }
}

// Sets the item filter on start
// This is only called on load
function set_view() {

    // Establish css behaviors
    set_navt_behaviors();

    // set the initial view
    var what = getCookie(vu_cookie);
    what = parseInt((what === null ? vu_all: what), 10);
    jQuery('#' + vu_select).setSelected(what);
    var nav_group = new NavGroup(id_default_group + sfx_nav_group_container);
    nav_group.filter(what);
}

/**
* Helper function
* Callback for drag/drop updates
* marks the groups with changebars
*/
function dropUpdate() {
    var nav_group = new NavGroup(this.element.id);
    nav_group.mark_changed();
}

/**
* Helper function
* Creates an XML document that is sent back to the server that describes
* the navigation groups and their contents.
*/
function updateCfg() {

    // locate and remove empty drop zones first
    var gDropZones = jQuery('.'+ css_nav_group_dropzone).each(
    function() {
        var id = this.id;
        var all = jQuery('#' + this.id + ' .mi');
        if( all.length === 0 && (this.id != (id_default_group + sfx_nav_group_container)) ) {
            // empty zone;
            var nav_group = new NavGroup(this.id);
            jQuery('#' + nav_group.root).remove();
            // nav_group.delete_group(nav_group.root);
        }
    });

    jQuery('#navt_spinner').show();
    var outdata = 'NAVT_xmldata=<navtmap>';

    jQuery('.' + css_nav_group_dropzone).each(
    function() {
        var nav_group = new NavGroup(this.id);
        var group_items = nav_group.get_group_items();
        outdata += nav_group.begin_xml();
        group_items.each(
        function () {
            var nav_item = new NavItem(this.id);
            outdata += nav_item.get_xmldata(nav_group);
        });
        outdata += nav_group.end_xml();
    });
    outdata += '</navtmap>';

    jQuery.ajax({

        url: navtpath + '/app/navtajax.php',
        processData: false,
        data: outdata,
        type: 'post',

        success: function(xml) {
            jQuery("status", xml).each(function(){
                var status_is = parseInt(jQuery(this).text(), 10);
                var ourDate = new Date();
                n = adjust_update();

                switch( status_is ) {
                    case xml_success: {
                        // remove all change bars from all items
                        // add a message to the top of the page
                        jQuery('.change').
                        each(function() {
                            jQuery(this).toggleClass(css_changebars);
                        });

                        // rebuild the group display
                        rebuild_groups();

                        jQuery('#pm' + n).text('Updated: ' +
                        ourDate.toLocaleString() );
                        break;
                    }
                    case xml_cfg_not_updated: {
                        jQuery('#pm' + n).text('No changes detected: ' +
                        ourDate.toLocaleString() );
                        break;
                    }
                    case xml_cfg_missing_data: {
                        jQuery('#pm' + n).text('NAVT-ERR:01 Data was not present: ' +
                        ourDate.toLocaleString() );
                        break;
                    }
                    case xml_cfg_bad_data: {
                        jQuery('#pm' + n).text('NAVT-ERR:02 Data was not readable: ' +
                        ourDate.toLocaleString() );
                        break;
                    }
                    default: {
                        break;
                    }
                }
            });
        },

        error: function(xml) {
            n = adjust_update();
            var ourDate = new Date();
            var msg = 'NAVT-ERR:03 - Request failed: ' + ourDate.toLocaleString();
            // incorrectly reported 404 error?
            jQuery('#pm' + n).text(msg);
        },

        complete: function() {
            // turn off spinner
            jQuery('#navt_spinner').hide();
            return;
        }
    });

    return false;
}

// Rebuilds the list of available groups and places them in the default group selection dropdown
function rebuild_groups() {

    // Get the selected group
    var active = jQuery('#navt_default_group').getSelected();

    // Remove all the current options from the control
    jQuery('#navt_default_group > option').each(
    function() {
        jQuery(this).remove();
    });

    var option = '';
    var select = jQuery('#navt_default_group');
    var gDropZones = jQuery('.'+ css_nav_group_dropzone).each(
    function() {
        var id = this.id;
        var nav_group = new NavGroup(id);
        var group_name = nav_group.root;
        option = '<option value="' + group_name + '">' + group_name.toLowerCase() + '</option>';
        jQuery(option).appendTo('#navt_default_group');
    });

    // Set the selected value
    jQuery('#navt_default_group').setSelected(active);
}

function updateVersionChecker() {
    // Get the setting and update the server
    var is_checked = jQuery('#NAVT_vercheck').isChecked();
    var outdata = 'NAVT_vercheck=' + is_checked;
    sendAjaxRequest(outdata, 'Version checking [' + ((is_checked) ? '+]': '-]'));
    return;
}

function updateTips() {
    // Get the setting and update the server
    var is_checked = jQuery('#NAVT_tips').isChecked();
    var outdata = 'NAVT_tips=' + is_checked;
    sendAjaxRequest(outdata, 'Tips/Help [' + ((is_checked) ? '+]': '-]'));

    if( is_checked ) {
        // show the help icons
        jQuery('.helpdiv').fadeIn("slow");
        NT_activate();
    }
    else {
        // hide the help icons
        jQuery('.helpdiv').fadeOut("slow");
        NT_deactivate();
    }
    return;
}

function updateDefaultCategory() {
    // Get the setting and update the server
    var outdata = 'NAVT_default_group='+ jQuery('#navt_default_group').val();
    sendAjaxRequest(outdata, 'Default assignment update:');
    return;
}

function sendAjaxRequest(xmldoc, complete_msg) {
    // Get the setting and update the server
    jQuery('#navt_spinner').show();

    jQuery.ajax({
        url: navtpath + '/app/navtajax.php',
        processData: false,
        data: xmldoc,
        type: 'post', // 'get' does not work with IE

        success: function(xml) {
            jQuery("status", xml).each(function(){
                var status_is = parseInt(jQuery(this).text(), 10);
                n = adjust_update();
                var ourDate = new Date();
                var msg = complete_msg + ': ' + ourDate.toLocaleString();
                switch( status_is ) {
                    case xml_success: {
                        jQuery('#pm' + n).text(msg);
                        break;
                    }

                    default: {
                        jQuery('#pm' + n).text('error: ' + status_is);
                        break;
                    }
                }
            });
        },

        error: function(xml) {
            n = adjust_update();
            var ourDate = new Date();
            var msg = 'NAVT-ERR:04 - request failed: ' + ourDate.toLocaleString();
            jQuery('#pm' + n).text(msg);
        },

        complete: function() {
            // turn off spinner
            jQuery('#navt_spinner').hide();
            return;
        }
    });

    return false;
}

function adjust_update() {

    var c = parseInt( jQuery('#nxtupdate').val(), 10 );
    var p;

    if( c === 0 ) {
        c = 1;
        p = 0;
    }
    else if( c >= 5 ) {
        c = 1;
        p = 5;
    }
    else {
        p = c;
        c++;
    }

    if( p !== 0 ) {
        jQuery('#pm' + p).removeClass('last_updated');
    }
    jQuery('#pm' + c).addClass('last_updated');
    jQuery('#nxtupdate').val(c);
    return(c);
}


// -------------------------------------------------------------------------
// My javascript extensions
// -------------------------------------------------------------------------

Object.extend(String.prototype, {

    trim: function() {
        return( this.replace(new RegExp("^([\\s]+)|([\\s]+)$", "gm"), "") );
    },

    fixquote: function() {
        return( this.replace(new RegExp("\"", "gm"), "'") );
    },

    uscore: function() {
        return( this.replace(new RegExp("\\s+", "gi"), "_") );
    },

    nophp: function() {
        return(this.replace( new RegExp("<\?", "g"), "") );
    },

    isAlpha: function() {
        return( this.match(/^[0-9a-zA-Z]+$/) );
    },

    isSameAs: function(text) {
        return(this == text ? 1: 0);
    },

    cleanGroupName: function() {
        var n = this;
        n = n.replace(new RegExp("\"", "gi"), "'");
        n = n.trim();
        n = n.camelize();
        n = n.stripScripts();
        n = n.stripTags();
        n = n.strip();
        n = n.uscore();
        n = n.truncate(max_group_name);
        n = n.toLowerCase();
        return(n);
    },

    clean: function() {
        var n = this;
        n = n.replace(new RegExp("\"", "gi"), "'");
        n = n.trim();
        n = n.stripScripts();
        n = n.stripTags();
        n = n.strip();
        n = n.nophp();
        return(n);
    },

    isEmpty: function() {
        var r = 1;
        if( this.length !== 0 && this !== '' ) {for(var i = 0; i < this.length && r; i++){if( this[i] !== ' ') r = 0;}}
        return(r);
    },

    cleanUrl: function() {
        var n = this;
        n = n.trim();
        n = n.stripScripts();
        n = n.nophp();
        return(n);
    },

    htmlent: function() {
        var n = this;
        n = n.replace(new RegExp("<", "gi"), "&lt;");
        n = n.replace(new RegExp(">", "gi"), "&gt;");
        n = n.replace(new RegExp("'", "gi"), "&apos;");
        n = n.replace(new RegExp('"', "gi"), "&quot;");
        //n = n.replace(new RegExp("&", "gi"), "&amp;");
        return(n);
    },

    replaceName: function(s, r) {
        var n = this;
        if( this.match(new RegExp(s, "gi")) ) {
            n = this.replace(new RegExp(s, "gi"), r);
        }
        return(n);
    }
});

// -------------------------------------------------------------------------
// My jQuery extensions
// -------------------------------------------------------------------------
jQuery.fn.extend({

    // is present - returns true if the DOM element is present
    isPresent: function() {
        return( this[0] ? 1: 0 );
    },

    // Has class function
    hasClass: function(c) {
        return( this.is("." + c) );
    },

    // Is a checkbox ticked ?
    isChecked: function() {
        return(this.isPresent() ? ( this.attr('checked') ? 1: 0 ) : 0 );
    },

    // Uncheck a checkbox
    unCheckIt: function() {
        if( this.isPresent() ) return(this.removeAttr('checked'));
    },

    // Check a checkbox
    checkIt: function() {
        if(this.isPresent()) return(this.attr('checked', 'checked'));
    },

    // Enable something
    enableIt: function() {
        if(this.isPresent()) return(this.removeAttr('disabled'));
    },

    // Disable something
    disableIt: function() {
        if(this.isPresent()) return( this.attr('disabled', 'disabled'));
    },

    // is Visible ?
    isVisible: function() {
        var status = this.css('display');
        return(!(status == 'none'));
    },

    // Clear out any text
    clear: function() {
        return( this.text(" ") );
    },

    // Empty a textbox
    flush: function() {
        return(this.val(''));
    },

    // grey - makes a control look disabled
    grey: function() {
        return( this.css({color: '#888'}) );
    },

    // ungrey - makes a control look enabled
    ungrey: function() {
        return( this.css({color: '#000'}) );
    },

    // set the html in an element
    set_contents: function(v) {
        return(this.html(v));
    },

    set_text: function(v) {
        return(this.text(v));
    },

    get_text: function(v) {
        return(this.text());
    },

    // Returns the value of an <input> control
    // as an integer
    getIntValue: function() {
        return( parseInt(this.val(), 10));
    },

    // Returns the value of an <input> control
    getValue: function() {
        return(this.val());
    },

    // Sets the value of an <input> control
    setValue: function(v) {
        this.val(v);
        return(this.val());
    },

    // Returns the value of a <select> control
    getSelected: function() {
        return(this.val());
    },

    // Sets the value of a <select> control
    setSelected: function(v) {
        this.val(v);
        return(this.val());
    },

    // Sets the focus
    setFocus: function() {
        this[0].focus();
        return(this);
    }

});

// -------------------------------------------------------------------------
// Cookie handling
// -------------------------------------------------------------------------

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

function getCookie(name) {
    var dc = document.cookie;
    var prefix = name + "=";
    var begin = dc.indexOf("; " + prefix);
    if (begin == -1) {
        begin = dc.indexOf(prefix);
        if (begin !== 0) return null;
    } else {
        begin += 2;
    }
    var end = document.cookie.indexOf(";", begin);
    if (end == -1) {
        end = dc.length;
    }
    return unescape(dc.substring(begin + prefix.length, end));
}

function deleteCookie(name, path, domain) {
    if (getCookie(name)) {
        document.cookie = name + "=" +
        ((path) ? "; path=" + path : "") +
        ((domain) ? "; domain=" + domain : "") +
        "; expires=Thu, 01-Jan-70 00:00:01 GMT";
    }
}


// --------------------------------------------------------------------
// group menu actions
// --------------------------------------------------------------------
function grp_menu(item, action) {

    var nav_group =  (action != 'open') ?
    new NavGroup(item.parentNode.id):
    new NavGroup(item.id);
    var nav_item;

    if( nav_group !== null ) {

        switch( action ) {
            case 'open':       nav_group.toggle_options_menu(); break;
            case 'rename':     nav_group.show_rename_controls(); break;
            case 'delete':     nav_group.show_delete_controls(); break;
            case 'addlink':    nav_item = new NavItem(null); nav_item.add_item(nav_group, item_is_elink); break;
            case 'adddiv':     nav_item = new NavItem(null); nav_item.add_item(nav_group, item_is_divider); break;
            case 'dropdown':   nav_group.toggle_dropdown(); break;
            case 'nostyle':    nav_group.toggle_nostyle(); break;
            case 'openall':    nav_group.open_all(); break;
            case 'closeall':   nav_group.close_all(); break;
            case 'restoreall': nav_group.restore_hidden(); break;
            default: break;
        }
    }

    return false;
}

// --------------------------------------------------------------------
// group button actions
// --------------------------------------------------------------------
function grp_click(item, action, button) {

    var nav_group = new NavGroup(item.parentNode.id);

    if( nav_group !== null ) {

        switch( action ) {
            case 'delete': {
                switch(button) {
                    case 'ok':     nav_group.deleteOk(); break;
                    case 'cancel': nav_group.deleteClose(); break;
                    default: break;
                }
                break;
            }

            case 'rename': {
                switch(button) {
                    case 'ok':     nav_group.renameOk(); break;
                    case 'cancel': nav_group.renameClose(); break;
                    default: break;
                }
                break;
            }
            default: {
                break;
            }
        }
    }

    return false;
}

// --------------------------------------------------------------------
// Item button actions
// --------------------------------------------------------------------
function item_click(item, action) {

    var nav_item = (action == 'open') ? new NavItem(item.id) : new NavItem(item.parentNode.id);

    if( nav_item !== null ) {

        switch( action ) {
            case 'open': {
                nav_item.optionbox(_open);
                break;
            }

            case 'ok': {
                nav_item.optionOk();
                break;
            }

            case 'cancel': {
                nav_item.optionCancel();
                nav_item.optionbox(_close);
                break;
            }

            case 'delete': {
                nav_item.optionDelete();
                break;
            }
            default: {
                break;
            }
        }
    }

    return false;
}

// fold/unfold a navigation group
//
function toggle_folder(item) {
    var nav_group = new NavGroup(item.id);

    if( jQuery('#' + nav_group.root + sfx_nav_group_container).isVisible() ) {
        jQuery('#' + nav_group.root + sfx_nav_group_container).fadeOut();
        jQuery('#' + nav_group.root + '_folder').removeClass('close');
        jQuery('#' + nav_group.root + '_folder').addClass('open');
    }
    else {
        jQuery('#' + nav_group.root + sfx_nav_group_container).fadeIn();
        jQuery('#' + nav_group.root + '_folder').removeClass('open');
        jQuery('#' + nav_group.root + '_folder').addClass('close');
    }
    return(false);
}

// --------------------------------------------------------------------
// Indent/Outdent for hierarchy
// --------------------------------------------------------------------
function indent(item) {
    var nav_item = new NavItem(item.id);
    nav_item.indent();
    return false;
}

function outdent(item) {
    var nav_item = new NavItem(item.id);
    nav_item.outdent();
    return false;
}

// Called only once.
function set_navt_behaviors() {

    // show or hide help icons
    var is_checked = jQuery('#NAVT_tips').isChecked();
    if( is_checked ) {
        // show the help icons
        jQuery('.helpdiv').fadeIn("slow");
        NT_activate();
    }
    else {
        // hide the help icons
        jQuery('.helpdiv').fadeOut("slow");
        NT_deactivate();
    }

    // Create a Navigation Group
    jQuery('#NAVT_addgroup').click(function() {
        var name = jQuery('#' + id_sys_textbox).getValue();
        name = name.toUpperCase(); // force to upper case
        var nav_group = new NavGroup(name);
        nav_group.createGroup();
        return false;
    });

    jQuery('#NAVT_update').click(function() {
        updateCfg();
        return false;
    });

    jQuery('#NAVT_vercheck').click(function() {
        updateVersionChecker();
        return true;
    });

    jQuery('#NAVT_tips').click(function() {
        updateTips();
        return true;
    });

    jQuery('#navt_default_group').click(function() {
        var cur = jQuery('#default_group_selection').getValue();
        var now_selected = jQuery(this).getSelected();

        if( cur != now_selected ) {
            updateDefaultCategory();
            jQuery('#default_group_selection').setValue(now_selected);
            return(true);
        }
        else {
            return false;
        }
    });

    // Item filter
    jQuery('#vuselect').click(function() {
        var now = new Date();
        now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000);
        var opt = parseInt( jQuery('#' + this.id).getSelected(), 10 );
        var nav_group = new NavGroup(id_default_group + sfx_nav_group_container);
        nav_group.filter(opt);
        setCookie(vu_cookie, opt, now, '', '', 0);
        return false;
    });

    // Open close help example
    jQuery('#css_ex1').click(function() {
        //Effect.toggle('css_example1', 'Slide', {duration: 1.8});
        return false;
    });

    // Open close section
    jQuery('#shf1').click(function() {
        //Effect.toggle('fold_issues', 'Slide', {duration: 1.8});
        return false;
    });

    // Open close section
    jQuery('#shf2').click(function() {
        //Effect.toggle('fold_compat', 'Slide', {duration: 1.8});
        return false;
    });
}