// ---------------------------------------------------------------------

function dnCreateTabViews (classname, unselectedClass, selectedClass, action) {
    if (!dnCreateTabViews.registry) dnCreateTabViews.registry = {};
  
    var tabViews = dnGetElementsByClassName(classname);
    for (var i = 0; i < tabViews.length; i++) {
        var config = {};
        config.tabUnselectedClass = unselectedClass;
        config.tabSelectedClass = selectedClass;
        config.tabPanelMap = {};
        
        var firstTab = null;
        var descendants = tabViews[i].getElementsByTagName("*");
        for (var j = 0; j < descendants.length; j++) {
            if (!descendants[j].id) continue;
            if (/^tab:/i.test(descendants[j].id)) {
                var name = /^tab:(.+)$/i.exec(descendants[j].id);
                config.tabPanelMap["tab:" + name[1]] = "panel:" + name[1];
                if (!firstTab) firstTab = descendants[j].id;
            }
        }
        if (action != 'roll') {
          config.tabInitSelected = firstTab; 
        }
        var controller = new dnTabViewController(config, action);
        dnCreateTabViews.registry[classname + i] = controller;
    }
};

// ---------------------------------------------------------------------

function dnTabViewController (config, action) {
    // Sanity check the config object.
    if (typeof(config) === "Object") {
        console.error("You must specify a configuration object.");
        return null;
    }
    else if (typeof(config.tabPanelMap) === "Object") {
        console.error("You must set supply a tabPanelMap config option.");
        return null;
    }
    
    // Instance variables.
    this.config = config;
    this.tabPanelMap = config.tabPanelMap;
    this.tabSelectedClass = config.tabSelectedClass;
    this.tabUnselectedClass = config.tabUnselectedClass;
    
    // Attach onclick event handler to the tabs.
    for (var tabId in this.tabPanelMap) {
        var panelId = this.tabPanelMap[tabId];
        
        // Check that we were given good ids.
        if (!$(tabId)) {
            console.error("Failed to find element '" + tabId + "'.");
            continue;
        }
        else if (!$(panelId)) {
            console.error("Failed to find element '" + panelId + "'.");
            continue;
        }
        
        var me = this;        
        if (action == 'roll'){         
         
          $(panelId).onmouseover = function () { me.showPanelForTab(this.parentNode, action); };
          $(tabId).onmouseout = function () { me.hideAll(); };          
          $(tabId).onmouseover = function () { me.showPanelForTab(this, action); };
          
        } else { 
          $(tabId).onclick = function () { me.showPanelForTab(this, action); };
        }
    }
    
    if (config.tabInitSelected) this.showPanelForTab($(config.tabInitSelected));
};

// ---------------------------------------------------------------------
// dnTabViewController.showPanelForTab()

dnTabViewController.prototype.showPanelForTab = function (tab, action) {
    var panelId = this.tabPanelMap[tab.id];
    if (action != "roll") this.hideAll();
    
    if (this.tabSelectedClass) tab.className = this.tabSelectedClass;
    // use this to offset the menu panels. Slows menu down.
    //if (action == 'roll') {
    //  $(panelId).style.left = dnFindPos($(tab.id))[0]-1+"px";
    //  var topPos = dnFindPos($(tab.id))[1];
    //  topPos += 16;
    //  $(panelId).style.top = topPos+"px";
    //} 
    $(panelId).style.display = "block";
};

// ---------------------------------------------------------------------
// dnTabViewController.hideAll()

dnTabViewController.prototype.hideAll = function () {
    for (var tabId in this.tabPanelMap) {
        var panelId = this.tabPanelMap[tabId];
        
        if (!$(panelId)) {
            console.error("Failed to find element '" + panelId + "'.");
            continue;
        }
        
        $(panelId).style.display = "none";
        $(tabId).className = this.tabUnselectedClass;
    }
};

// ---------------------------------------------------------------------