﻿
/*
 * jNova 0.9
 *
 * Copyright (c) 2008 Kei Takahashi
 *
 * Date: 10:17 PM 12/5/2008 
 * Rev:  0001 
 */
 
//---------------------------------------------------------------
// jNovaU
//---------------------------------------------------------------
var jNovaU = {
  isArray: function(obj) {
    return (obj.length != null) && 
           (obj.split == null) &&  // not string
           (obj.setInterval == null) && // not window
           (obj.call == null); // not function
  },
  
  pushToArray: function(obj, output) {
    if (jNovaU.isArray(obj))
    {
      for (var i = 0; i < obj.length; i++)
        jNovaU.pushToArray(obj[i], output);
    }
    else
    {
      output.push(obj);
    }
  },

  makeFlatArray: function(obj) {
    var flatArray = [];
    jNovaU.pushToArray(obj, flatArray);
    return flatArray;
  },

  setStyle: function(style, jq) {
    if (style)
    {
      var array = jNovaU.makeFlatArray(style);
      
      for (var i=0; i < array.length; i++)
        jq.addClass(array[i]);
    }
  }
}

//---------------------------------------------------------------
// jNova
//---------------------------------------------------------------

var jNova = {

  tabCurIndex: 0,
  vtabCurIndex: 0,

  makePara: function(data, indent, jq) {
    var array = jNovaU.makeFlatArray(data);
    var para;    
    for (var i=0; i < array.length; i++)
    {
      para = jq.append("<p></p>").children(":last");
      para.html(array[i]);
      
      if (indent)
      {
        para.addClass("p-indent");
      }    
    }
    
    para.addClass("p-last");
  },
  
  makeList: function(data, style, ordered, jq) {
    if (ordered)
    {
      jq.append("<ol></ol>");
    }
    else
    {
      jq.append("<ul></ul>");
    }
    
    var list = jq.children(":last");
    jNovaU.setStyle(style, list);

    var array = jNovaU.makeFlatArray(data);      
    
    for (var i=0; i < array.length; i++)
    {
      jNova.generateDocCore(array[i], list.append("<li></li>").children(":last"));
    }
  },
  
  makeBlock: function(data, style, jq) {
    var jqDiv = jq.append("<div></div>").children(":last");

    if (style)
      jNovaU.setStyle(style, jqDiv);
      
    if (data)
      jNova.generateDocCore(data, jqDiv);  
    
  },
  
  makeSpan: function(data, style, jq) {
    var jqSpan = jq.append("<span></span>").children(":last");
    
    if (style)
      jNovaU.setStyle(style, jqSpan);
    
    if (data)
      jqSpan.html(data.toString());
  },
  
  makeTable: function(data, style, jq) { /* does not work in IE */
    if (jNovaU.isArray(data)) {
      var jqTable = jq.append("<table></table>").children(":last");
      
      if (data.style)
      {
        jqTable.addStyle(data.style);
      }
      
      for (var i=0; i < data.length; i++) {
        if (jNovaU.isArray(data[i])) {
          var jqRow = jqTable.append("<tr></tr>").children(":last");
          for (var j=0; j < data[i].length; j++) {
            var jqCell = jqRow.append("<td></td>").children(":last");
            jNova.generateDocCore(data[i][j], jqCell);
          }
        }
      }
    }
  },
  
  makeTabCtrl: function(unit, jq) {
    if (unit.data)
    {
      jNova.tabCurIndex += 1;
      
      var jqTopContainer = jq.append("<div></div>").children(":last");
      
      var jqTabDiv = jqTopContainer.append("<div></div>").children(":last");
      var jqTabUl = jqTabDiv.append("<ul></ul>").children(":last");
      
      jqTabDiv.addClass("tabctrl-tab-group-container");
      jqTabUl.addClass("tabctrl-tab-group");
      
      /* any use case ?
      if (unit.styleTabGroup)
      {
        jNovaU.setStyle(unit.styleTabGroup, jqTabDiv);
      }
      */
      
      var activeTabStyle = unit.overrideStyleActiveTab ? unit.overrideStyleActiveTab : "tabctrl-default-active-tab";
      var inactiveTabStyle = unit.overrideStyleInactiveTab ? unit.overrideStyleInactiveTab : "tabctrl-default-inactive-tab";
      var contentsDefaultStyle = unit.overrideStyleContents ? unit.overrideStyleContents : "tabctrl-default-contents";
      
      jqTabDiv.data("activeTabStyle", activeTabStyle);
      jqTabDiv.data("inactiveTabStyle", inactiveTabStyle);
      
      var array = jNovaU.makeFlatArray(unit.data);
      var idStartWith = "tab-" + jNova.tabCurIndex + "-";
      
      for (var i=0; i < array.length; i++)
      {
        var item = array[i];
        
        if (item.tab)
        {
          var id = idStartWith + (i + 1); 
          var jqLi = jqTabUl.append("<li></li>").children(":last").html(item.tab.toString()).addClass("tabctrl-tab").attr("id", id);
          
          if (i == 0)
          {
            jqLi.addClass("tabctrl-tab-active").addClass(activeTabStyle);
          }
          else
          {
            jqLi.addClass(inactiveTabStyle);
          }
          
          if (unit.styleTab)
          {
            jNovaU.setStyle(unit.styleTab, jqLi);
          }
          
          var jqContents = jqTopContainer.append("<div></div>").children(":last").addClass("tabctrl-contents").addClass(contentsDefaultStyle).attr("id", id + "-contents");
          if (item.data)
          {
            jNova.generateDocCore(item.data, jqContents);
          }
          
          if (unit.styleContents)
          {
            jNovaU.setStyle(unit.styleContents, jqContents);
          }
        }      
      }
      
      jq.append("<div></div>").children(":last").addClass("float-end");
    }  
  },
  
  makeVTabCtrl: function(unit, jq) {
    if (unit.data)
    {
      jNova.vtabCurIndex += 1;
      
      var jqTopCotainer = jq.append("<div></div>").children(":last");
      
      var jqTabDiv = jqTopCotainer.append("<div></div>").children(":last");
      var jqTabUl = jqTabDiv.append("<ul></ul>").children(":last");
      
      jqTabDiv.addClass("vtabctrl-tab-group-container");
      jqTabUl.addClass("vtabctrl-tab-group");
      
      /* any use case ?
      if (unit.styleBar)
      {
        jNovaU.setStyle(unit.styleBar, jqVBarDiv);
      }
      */
      
      var activeTabStyle = unit.overrideStyleActiveTab ? unit.overrideStyleActiveTab : "vtabctrl-default-active-tab";
      var inactiveTabStyle = unit.overrideStyleInactiveTab ? unit.overrideStyleInactiveTab : "vtabctrl-default-inactive-tab";
      var contentsDefaultStyle = unit.overrideStyleContents ? unit.overrideStyleContents : "vtabctrl-default-contents";

      var tabWidthStyle = unit.overrideStyleTabWidth ? unit.overrideStyleTabWidth : "vtabctrl-default-tab-width";
      var contentsMarginStyle = unit.overrideStyleContentsLeftMargin ? unit.overrideStyleContentsLeftMargin : "vtabctrl-default-contents-margin";
      var contentsHeightStyle = unit.overrideStyleContentsMinHeight ? unit.overrideStyleContentsMinHeight : "vtabctrl-default-contents-height";

      jqTabDiv.data("activeTabStyle", activeTabStyle);
      jqTabDiv.data("inactiveTabStyle", inactiveTabStyle);
      
      var array = jNovaU.makeFlatArray(unit.data);
      var idStartWith = "vtab-" + jNova.vtabCurIndex + "-";
      
      for (var i=0; i < array.length; i++)
      {
        var item = array[i];
        
        if (item.tab)
        {
          var id = idStartWith + (i + 1); 
          var jqLi = jqTabUl.append("<li></li>").children(":last").html(item.tab.toString()).addClass("vtabctrl-tab").addClass(tabWidthStyle).attr("id", id);
          
          if (i == 0)
          {
            jqLi.addClass("vtabctrl-tab-active").addClass(activeTabStyle);
          }
          else
          {
            jqLi.addClass(inactiveTabStyle);
          }
          
          if (unit.styleTab)
          {
            jNovaU.setStyle(unit.styleTab, jqLi);
          }
          
          var jqContents = jqTopCotainer.append("<div></div>").children(":last").addClass("vtabctrl-contents").addClass(contentsDefaultStyle).addClass(contentsMarginStyle).addClass(contentsHeightStyle).attr("id", id + "-contents");
          if (item.data)
          {
            jNova.generateDocCore(item.data, jqContents);
          }
          
          if (unit.styleContents)
          {
            jNovaU.setStyle(unit.styleContents, jqContents);
          }
        }      
      }
      
      jq.append("<div></div>").children(":last").addClass("float-end");
    }
  },
  
  makeImgList: function(unit, jq) {
    if (unit.data) {
      var jqContainer = jq.append("<div></div>").children(":last");
      
      if (unit.style) {
        jNovaU.setStyle(unit.style, jqContainer);
      }
      
      var array = jNovaU.makeFlatArray(unit.data);
      
      for (var i=0; i < array.length; i++) {
      
        var jqBlock = jqContainer.append("<div></div>").children(":last");

        var jqImgDiv = jqBlock.append("<div></div>").children(":last");
        var jqContentsDiv = jqBlock.append("<div></div>").children(":last");

        jqImgDiv.addClass("float-left");
        
        var defaultStyleImg = unit.overrideStyleImgWidth ? unit.overrideStyleImg : "width-ten";
        var defaultStyleContents = unit.overrideStyleContentsLeftMargin ? unit.overrideStyleContentsLeftMargin : "margin-left-ten";

        jqImgDiv.addClass(defaultStyleImg);
        jqContentsDiv.addClass(defaultStyleContents);
        
        if (unit.styleImg) {
            jNovaU.setStyle(unit.styleImg, jqImgDiv);
        }

        if (unit.styleContents) {
            jNovaU.setStyle(unit.styleContents, jqContentsDiv);
        }
        
        if (array[i].img) {
          jNova.generateDocCore(array[i].img, jqImgDiv);
        }
                
        if (array[i].data) {
          jNova.generateDocCore(array[i].data, jqContentsDiv);
        }
        
        jNova.generateDocCore(floatEnd, jqBlock);                
      }
    }
  },
  
  generateDocCore: function(units, jq) {
    var array = jNovaU.makeFlatArray(units);
    for (var i=0; i < array.length; i++)
    {
      var unit = array[i];
      
      if (unit.type)
      {
        switch (unit.type)
        {
          case "para":
            if (unit.data)
            {
              jNova.makePara(unit.data, unit.indent, jq);
            }
            break;
          case "block":
            jNova.makeBlock(unit.data, unit.style, jq);
            break;
          case "list":
            if (unit.data)
            {
              jNova.makeList(unit.data, unit.style, unit.ordered, jq);
            }
            break;
          case "span":
            if (unit.data)
            {
              jNova.makeSpan(unit.data, unit.style, jq);
            }
            break;
          case "table":
            if (unit.data)
            {
              jNova.makeTable(unit.data, unit.style, jq);
            }
          case "tabctrl":
            if (unit.data)
            {
              jNova.makeTabCtrl(unit, jq);
            }
            break;
          case "vtabctrl":
            if (unit.data)
            {
              jNova.makeVTabCtrl(unit, jq);
            }
            break;
           case "imglist":
            if (unit.data)
            {
              jNova.makeImgList(unit, jq);329
            }
          default:
            break;  
        }
      }
      else
      {
        if (unit.data)
        {
            jq.append(unit.data);
        }
        else
        {
          jq.append(unit.toString());
        }
      }
    }  
  },
  
  generateDoc: function(doc, jq) {
    if (jq == null)
    {
      jq = $("body");
    }

    jNova.generateDocCore(doc, jq);
  },
  
  initCtrls: function() {
    initializeTabs();
    initializeVTabs();  
  }
}

//---------------------------------------------------------------
// Tab control
//---------------------------------------------------------------
function initializeTabs() {
  $(".tabctrl-tab").click(onTabClick);
  showHideTabContents();
}

function onTabClick() {
  var src = $(this);
  if (!src.hasClass("tabctrl-tab-active")) {
  
    var tabGroupContainer = src.parents(".tabctrl-tab-group-container:first"); 
    var activeStyle = tabGroupContainer.data("activeTabStyle");
    var inactiveStyle = tabGroupContainer.data("inactiveTabStyle");
  
    src.siblings(".tabctrl-tab").removeClass("tabctrl-tab-active").removeClass(activeStyle).addClass(inactiveStyle);
    src.addClass("tabctrl-tab-active").addClass(activeStyle).removeClass(inactiveStyle);
    
    showHideTabContents(src);
  }
}

function showHideTabContents(activeTab) {
  if (activeTab == null) {
    activeTab = $(".tabctrl-tab-active");
  }
  
  activeTab.each( function() {
    var toShow = $("#" + $(this).attr("id") + "-contents");
    toShow.show();
    toShow.siblings(".tabctrl-contents").hide();
  });
}

//---------------------------------------------------------------
// Vertical Tab control
//---------------------------------------------------------------
function initializeVTabs() {
  $(".vtabctrl-tab").click(onVTabClick);
  showHideVTabContents();
  
  /* this part does not work well on Chrome (works on IE, Firefox)
  
  $(".vtab-bar-container").each( function() {
    var container = $(this);
    var width = container.width();
    var height = container.height();
    
    container.siblings(".vtab-contents").css("margin-left", width).css("min-height", height);    
  });
  */
}

function onVTabClick() {
  var src = $(this);
  if (!src.hasClass("vtabctrl-tab-active")) {
  
    var tabGroupContainer = src.parents(".vtabctrl-tab-group-container:first");
    var activeStyle = tabGroupContainer.data("activeTabStyle");
    var inactiveStyle = tabGroupContainer.data("inactiveTabStyle");
    
    src.siblings(".vtabctrl-tab").removeClass("vtabctrl-tab-active").removeClass(activeStyle).addClass(inactiveStyle);
    src.addClass("vtabctrl-tab-active").addClass(activeStyle).removeClass(inactiveStyle);
    
    showHideVTabContents(src);
  }
}

function showHideVTabContents(activeTab) {
  if (activeTab == null) {
    activeTab = $(".vtabctrl-tab-active");
  }
  activeTab.each( function() {
    var toShow = $("#" + $(this).attr("id") + "-contents");
    toShow.show();
    toShow.siblings(".vtabctrl-contents").hide();
  });
}  




//---------------------------------------------------------------
// Predefined component
//---------------------------------------------------------------

var blankLine = { type: "block",
                  style: "height-one",
                  data: "&nbsp;" };


var floatEnd = { type: "block",
                 style: "float-end" };