/*************************************************************************
    This code is from Dynamic Web Coding at dyn-web.com
    Copyright 2009 by Sharon Paine 
    See Terms of Use at www.dyn-web.com/business/terms.php
    regarding conditions under which you may use this code.
    This notice must be retained in the code as is!
*************************************************************************/

// requires: dw_event.js, dw_cookies.js (2009 version)

// arguments: Tid is id of container (div or list element)
// tag: list type (ul, ol, dl)
// collapse previous, use cookies (supported only for ul and ol and only for one level nesting)
function dw_Toggle(Tid, tag, bColPrev, bUseCookies) {
    this.Tid = Tid; this.tag = tag || 'ul'; 
    this.colPrev = bColPrev; this.useCookies = bUseCookies;
    dw_Toggle.col[Tid] = this;
    
    switch (this.tag) {
        case 'ul' :
        case 'ol' :
            this.init(Tid);
            break;
        case 'dl' :
            this.init_DL(Tid);
            break;
    }
}

dw_Toggle.col = {} // instances collection

dw_Toggle.hasBrowserSupport = function() {
    if ( document.getElementById && document.getElementsByTagName 
         && typeof decodeURI !== 'undefined'
         && (document.addEventListener || document.attachEvent) ) {
        return true;
    }
    return false;
}

dw_Toggle.prototype = {
    current: null, // id of currently active 
    cur_actuator: null, // element that activated current 

    init: function(Tid) {
        var links = dw_Util.getElementsByClassName( 'has_sub', 'a', document.getElementById(Tid) );
        var c, id;
        
        if ( this.useCookies ) {
            c = dw_Toggle.checkCookie(Tid);
        }
        for (var i=0; links[i]; i++) {
            var lnk = links[i];
            // colPrev or useCookies? need id
            id = (lnk.parentNode.getElementsByTagName( this.tag ) )[0].id;
            if ( id && this.colPrev || this.useCookies ) {
                lnk.href = '#' + id + '__' + Tid;
                
                if (c && c === id ) {
                    dw_Util.addClass(lnk, 'expanded');
                    dw_Util.addClass(document.getElementById(c), 'revealed');
                    this.current = id;
                    this.cur_actuator = lnk;
                }
            }
            dw_Event.add( lnk, 'click', dw_Toggle.doToggle );
        }           
        
    },
    
    init_DL: function(Tid) {
        var els = document.getElementById(Tid).getElementsByTagName('dt');
        for (var i=0; els[i]; i++) {
            dw_Event.add( els[i], 'click', dw_Toggle.doToggle );
        }
    }
}

dw_Toggle.doToggle = function(e) {
    var el, _this;
    var tgt = dw_Event.getTarget(e);
    // can't necessarily get instance (for  _this.tag)
    var list = tgt.parentNode.getElementsByTagName('ul');
    if ( list.length == 0 ) {
        list = tgt.parentNode.getElementsByTagName('ol');
    }
    if ( list[0] ) {
        el = list[0];
    } else  if ( tgt.tagName.toLowerCase() === 'dt' ) {
        el = tgt.nextSibling; // get next dd
        while ( el.nodeType != 1 ) {
            el = el.nextSibling;
        } 
    }    
    if (!el) return true;
    
    // If cookies and/or current supported, tgt would be link with href # and '__' (means of obtaining instance)
    if ( tgt.tagName.toLowerCase() === 'a' && tgt.href.indexOf('#') !== -1 ) {
        var ids = tgt.href.slice( tgt.href.indexOf('#') + 1 );
        var el_id = ids.slice (0, ids.lastIndexOf('__') );
        var Tid = ids.slice ( ids.lastIndexOf('__') + 2 ); // id used to create dw_Toggle instance
        _this = dw_Toggle.col[Tid]
    }
    
    if ( dw_Util.hasClass(tgt, 'expanded' ) ) {
        dw_Util.removeClass(tgt, 'expanded');
        dw_Util.removeClass(el, 'revealed');
        if (_this) {
            _this.current = '';
            _this.cur_actuator = null;
            if ( _this.useCookies ) {
                dw_Toggle.delCookie(Tid, '/');
            }
        }
    } else {
        dw_Util.addClass(tgt, 'expanded');
        dw_Util.addClass(el, 'revealed');
        if (_this) {
            if ( _this.current ) {
                var cur_el = document.getElementById(_this.current);
                dw_Util.removeClass(cur_el, 'revealed');
                dw_Util.removeClass(_this.cur_actuator, 'expanded');
            }
            _this.current = el_id;
            _this.cur_actuator = tgt;
            if ( _this.useCookies ) {
                dw_Toggle.setCookie(Tid, el_id, null, '/');
            }
        }
    }
    e.preventDefault();
    return false;
}

dw_Toggle.expandAll = function(Tid) {
    var _this = dw_Toggle.col[Tid];
    // get links with class has_sub. add class 'expanded'
    var links = dw_Util.getElementsByClassName('has_sub', 'a', document.getElementById(Tid) );
    
    for (var i=0; links[i]; i++) {
        if ( !dw_Util.hasClass(links[i], 'expanded') ) {
            dw_Util.addClass(links[i], 'expanded');
        }
        // get ul's/ol's in parentNode. add class 'revealed'
        var list = links[i].parentNode.getElementsByTagName( _this.tag )[0];
        if ( !dw_Util.hasClass(list, 'revealed') ) {
            dw_Util.addClass(list, 'revealed');
        }
    }
    dw_Toggle.undoCur(Tid);
    return false;
}

dw_Toggle.expandAll_DL = function(Tid) {
    // for dl, dt's get expanded, dd's get revealed 
    var dl = document.getElementById(Tid).getElementsByTagName('dl');
    var dts = dl[0].getElementsByTagName('dt');
    var dds = dl[0].getElementsByTagName('dd');
    for (var i=0; dts[i]; i++) {
        if ( !dw_Util.hasClass(dts[i], 'expanded') ) {
            dw_Util.addClass(dts[i], 'expanded');
        }
        if ( !dw_Util.hasClass(dds[i], 'revealed') ) {
            dw_Util.addClass(dds[i], 'revealed');
        }
    }
    dw_Toggle.undoCur(Tid);
    return false;
}

dw_Toggle.hideAll = function(Tid) {
    var _this = dw_Toggle.col[Tid], links, list;
    var tgtTag, elTag, i;
    switch ( _this.tag ) {
        case 'ul' :
            tgtTag = 'a';
            elTag = 'ul';
            break;
        case 'ol' :
            tgtTag = 'a';
            elTag = 'ol';
            break;
        case 'dl' :
            tgtTag = 'dt';
            elTag = 'dd';
            break;
    }
    
    // links, dt's with class 'expanded', ul/ol/dl with class 'revealed'
    links = dw_Util.getElementsByClassName('expanded', tgtTag, document.getElementById(Tid) );
    for (i=0; links[i]; i++) {
        dw_Util.removeClass(links[i], 'expanded');
    }
    list = dw_Util.getElementsByClassName('revealed', elTag, document.getElementById(Tid) );
    for (i=0; list[i]; i++) {
        dw_Util.removeClass(list[i], 'revealed');
    }
    dw_Toggle.undoCur(Tid);
    return false;
}

// on expand/hide, undo cookies and current
dw_Toggle.undoCur = function(Tid) {
    var _this = dw_Toggle.col[Tid];
    if ( _this.current ) {
        _this.current = '';
        _this.cur_actuator = null;
    }
    if ( _this.useCookies ) {
        dw_Toggle.delCookie(Tid, '/');
    }
}

/////////////////////////////////////////////////////////////////////
//  cookie fn's (for multiple cookie storage under name 'dw_Toggle')
dw_Toggle.setCookie = function(Tid, id) {
    // format for cookies (multiple instances supported): dw_Toggle=Tid:id,Tid:id;
    var new_toggle_cookies = '';
    var toggle_cookies = dw_Cookie.get('dw_Toggle');
    if ( toggle_cookies ) {
        var cookies = toggle_cookies.split(',');
        for (var i=0; cookies[i]; i++) {
            if ( cookies[i].indexOf(Tid + ':') == 0 ) {
                cookies[i] = Tid + ':' + id;
                new_toggle_cookies = cookies.join(',');
                break;
            }
        }
        if ( !new_toggle_cookies ) { // if no match for this Tid
            new_toggle_cookies = toggle_cookies + ',' + Tid + ':' + id;
        }
    } else { // no dw_Toggle cookie set yet
        new_toggle_cookies = Tid + ':' + id;
    }
    dw_Cookie.set('dw_Toggle', new_toggle_cookies, null, '/');
}

dw_Toggle.delCookie = function(Tid) {
    var new_toggle_cookies = '';
    var toggle_cookies = dw_Cookie.get('dw_Toggle');
    if ( toggle_cookies ) {
        var cookies = toggle_cookies.split(',');
        for (var i=0; cookies[i]; i++) {
            if ( cookies[i].indexOf(Tid + ':') == 0 ) {
                cookies.splice(i, 1);
                new_toggle_cookies = cookies.join(',');
                dw_Cookie.set('dw_Toggle', new_toggle_cookies, null, '/');
            }
        }
    }
}

dw_Toggle.checkCookie = function(Tid) {
    var c, toggle_cookies = dw_Cookie.get('dw_Toggle');
    if ( toggle_cookies ) {
        var cookies = toggle_cookies.split(',');
        for (var i=0; cookies[i]; i++) {
            c = cookies[i];
            if ( c.indexOf(Tid + ':') == 0 ) {
                return decodeURI( c.slice(Tid.length + 1, c.length) );
            }
        }
    }
    return null;
}

/////////////////////////////////////////////////////////////////////
//  utility functions

var dw_Util; 
if (!dw_Util) dw_Util = {};

dw_Util.normalizeString = function (str) {
    var re = /\s\s+/g;
    return dw_Util.trimString(str).replace(re, " ");
}

dw_Util.trimString = function (str) {
    var re = /^\s+|\s+$/g;
    return str.replace(re, "");
}

dw_Util.addClass = function (el, cl) {
    el.className = dw_Util.trimString( el.className + ' ' + cl );
}

dw_Util.removeClass = function (el, cl) {
    el.className = dw_Util.normalizeString( el.className.replace(cl, " ") );
}

dw_Util.hasClass = function (el, cl) {
    var re = new RegExp("\\b" + cl + "\\b", "i");
    if ( re.test( el.className ) ) {
        return true;
    }
    return false;
}

// what className attached to what element type in what container element (default: document)
dw_Util.getElementsByClassName = function (sClass, sTag, oCont) {
    var result = [], list, i;
    var re = new RegExp("\\b" + sClass + "\\b", "i");
    oCont = oCont? oCont: document;
    if ( document.getElementsByTagName ) {
        if ( !sTag || sTag == "*" ) { // for ie5
            list = oCont.all? oCont.all: oCont.getElementsByTagName("*");
        } else {
            list = oCont.getElementsByTagName(sTag);
        }
        for (i=0; list[i]; i++) 
            if ( re.test( list[i].className ) ) result.push( list[i] );
    }
    return result;
}

dw_Util.writeStyleRule = function(rule, bScreen) {
    var screen = (bScreen != false)? ' media="screen">': '>';
    document.write( '\n<style type="text/css"' + screen + rule + '</style>');
}

/////////////////////////////////////////////////////////////////////
//  write style rules
if ( dw_Toggle.hasBrowserSupport() ) {
    // uses document.write (another function available using DOM methods)
    dw_Util.writeStyleRule(
        'ul.toggle_sub ul { display:none; }\n' + 
        'ol.toggle_sub ol { display:none; }\n' + 
        'dl.toggle dd { display:none; }\n' + 
        'dl.toggle dt { cursor:pointer; cursor:hand; }'
    );
}
