// $Id: index.js,v 1.12 2009/12/06 16:23:21 jdl Exp jdl $
//
// Copyright(c) 2009 by Joe Linoff
//
// You can copy and modify this software for your own use. I would
// appreciate a citation but do not requre it. There is no implied
// or express warranty for this software.
//
// This is unobtrusive javascript. Simply by referencing this script
// in the HTML with
//
//     <link href="css/index.css" rel="stylesheet" type="text/css" />
//    <script src="js/index.js"></script>
//
// you will auto load and setup the tab panels and colors.
//
// This script scans through the DOM looking for elements with the
// jdlIndexTab attribute. The elements are usually div objects. If it
// has a jdlIndexTab attribute it is a tab.  The value of the
// jdlIndexTab attribute is an id, in my example the id is something
// like "page1" or "page5". This id is used to to match up the tab
// with a tab panel. The tab panel is an element (usually a div) that
// has a single id attribute that matches the value in the jdlIndexTab
// attribute of the tab.
//
// Here is a very simple HTML example that shows this works:
//
// <html>
//   <header>
//     <link href="css/index.css" rel="stylesheet" type="text/css" />
//     <script src="js/index.js"></script>
//   </header>
//   <body>
//     <!--                                           -->
//     <!-- use table to make the tabs align properly -->
//     <!--                                           -->
//     <table style="text-align: left;" border="0" cellpadding="0" cellspacing="0">
//       <tbody>
//         <tr>
//           <td>&nbsp;&nbsp;</td>
//           <td>
//             <div jdlIndexTab="page1">&nbsp;Home&nbsp;</div>
//           </td>
//           <td>&nbsp;</td>
//           <td>
//             <div jdlIndexTab="page2">&nbsp;Downloads&nbsp;</div>
//           </td>
//           <td>&nbsp;</td>
//           <td>
//             <div jdlIndexTab="page3">&nbsp;Color Picker&nbsp;</div>
//           </td>
//         </tr>
//       </tbody>
//     </table>
//     <!--                  -->
//     <!-- Page 1 tab panel -->
//     <!--                  -->
//     <div id="page1">
//       <table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
//        <tbody>
//          <tr>
//            <td style="vertical-align: top;"><br>
//              Page 1 contents.
//            </td>
//          </tr>
//        </tbody>
//      </table>
//     <!--                  -->
//     <!-- Page 2 tab panel -->
//     <!--                  -->
//     <div id="page2">
//       <table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
//        <tbody>
//          <tr>
//            <td style="vertical-align: top;"><br>
//              Page 2 contents.
//            </td>
//          </tr>
//        </tbody>
//      </table>
//     <!--                  -->
//     <!-- Page 3 tab panel -->
//     <!--                  -->
//     <div id="page3">
//       <table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
//        <tbody>
//          <tr>
//            <td style="vertical-align: top;"><br>
//              Page 3 contents.
//            </td>
//          </tr>
//        </tbody>
//      </table>
//   </body>
// </html>
//
// The tables are used to make everything align. They could be inserted
// automatically but I like the flexibility to being able to define
// them explicitly so that I can experiment with the look and feel.
//
// The technique used here for onload is very primitive but extremely
// simple. It is based on replacing window.onload.
//
// The figure below shows how I defined a simple class named Index in
// the jdl namespace and instantiated it as a singleton. I then call
// jdl.Index.Main() to get things going when the script is loaded.
//
// The class has the following layout in C++ like pseudo-code:
//
// namespace jdl
// {
//    class Index
//    {
//    public:
//       var m_tab = null;
//       var m_page = null;
//       function GradientAdjust() {...}
//       function Gradient() {...}
//       function Setup() {...}
//       function Main() {...}
//    };
// }
//
// In javascript namespaces and classes are defined using JSON syntax.
var jdl = jdl ? jdl : {};
jdl.Index = function() {
  return {
    m_tab : null,
    m_page : null,
    GradientAdjust : function(v)
    {
      if (v<0)
	return 0;
      if (v>255)
	return 0;
      return v;
    },
    Gradient : function(h,s,r0,g0,b0,r1,g1,b1)
    {
      r0 = jdl.Index.GradientAdjust(r0);
      g0 = jdl.Index.GradientAdjust(g0);
      b0 = jdl.Index.GradientAdjust(b0);
      
      r1 = jdl.Index.GradientAdjust(r1);
      g1 = jdl.Index.GradientAdjust(g1);
      b1 = jdl.Index.GradientAdjust(b1);
      
      var rs = (r1-r0)/s;
      var gs = (g1-g0)/s;
      var bs = (b1-b0)/s;
      
      var e0 = document.getElementById("jdlIndexGradient");
      
      var div0 = document.createElement("div");
      //div0.style.position = 'absolute';
      div0.style.left = e0.style.left;
      div0.style.top = e0.style.top;
      div0.style.zIndex = 0;
      div0.style.borderWidth = 0;
      div0.style.borderHeight = 0;
      
      var table = document.createElement("table");
      table.border = 0;
      table.style.borderWidth = 0;
      table.style.borderHeight = 0;
      table.cellPadding = 0;
      table.cellSpacing = 0;
      table.width = "100%";
      
      var tbody = document.createElement("tbody");
      var tr = document.createElement("tr");
      tbody.appendChild(tr);
      table.appendChild(tbody);
      div0.appendChild(table);
      e0.parentNode.appendChild(div0); // sibling
      
      for(var i=0;i<s;i++) {
	var td = document.createElement("td");
	
	var r = Math.round(r0);
	var g = Math.round(g0);
	var b = Math.round(b0);
	var rgb = "rgb(" + r + "," + g + "," + b + ")";
	var div = document.createElement("div");
	div.style.backgroundColor = rgb;
	div.style.height = h;
	div.style.borderWidth = 0;
	div.style.borderHeight = 0;
	
	td.appendChild(div);
	tr.appendChild(td);
	
	r0 = jdl.Index.GradientAdjust(r0+rs);
	g0 = jdl.Index.GradientAdjust(g0+gs);
	b0 = jdl.Index.GradientAdjust(b0+bs);
      }
    },
    Setup : function()
    {
      // Attach event handlers.
      // Find all of the elements that have the "page" attribute.
      var body = document.getElementsByTagName("body")[0];
      var elements = body.getElementsByTagName("*");
      var first_tab = null;
      for(var i=0; i<elements.length; i++) {
        var element = elements[i];
        var pageid = element.getAttribute('jdlIndexTab');
        if (pageid != null) {
          if (first_tab == null) {
	    first_tab = element;
	  }
	  element.className = "jdlIndexTabUnSel";
          
          // register handlers
          element.onclick = function()
            {
              var e=this;
              if (jdl.Index.m_tab != e) {
		// De-select the previously selected tab.
                jdl.Index.m_page.className = "jdlIndexTabPanelUnSel";
                jdl.Index.m_tab.className = "jdlIndexTabUnSel";
              }

	      // Select the currently clicked tab.
              var pageid = e.getAttribute('jdlIndexTab');
              var page = document.getElementById(pageid);
	      page.className = "jdlIndexTabPanelSel";
	      e.className = "jdlIndexTabSel";
              jdl.Index.m_page = page;
              jdl.Index.m_tab  = e;
            }
        }

	// Now setup of the tab panel attributes.
 	var page = document.getElementById(pageid);
        if (page) {
	  page.className = "jdlIndexTabPanelUnSel";
        }
      }
      
      // Setup the initial display.
      if (first_tab) {
 	var pageid = first_tab.getAttribute('jdlIndexTab');
 	var page = document.getElementById(pageid);
 	if (page) {
	  first_tab.className = "jdlIndexTabSel";
	  page.className = "jdlIndexTabPanelSel";
 	  jdl.Index.m_page = page;
	  jdl.Index.m_tab = first_tab;
 	}
      }
      
      // Enable the color picker page. This is an example
      // of how to use forms without submit buttons.
      for(var i=0;i<document.color_picker.elements.length;i++) {
        var e1 = document.color_picker.elements[i];
        if (e1.type == "text") {
          var name = e1.getAttribute('name');
          //alert("Name:"+name);
          var e2 = document.getElementById(name);
          e2.style.backgroundColor = e1.value;
          e1.onchange = function()
            {
              var e=this;
              var name = e.getAttribute('name');
              var e2 = document.getElementById(name);
              e2.style.backgroundColor = e.value;
            }
        }
      }

      // Now setup the gradient.
      //jdl.Index.Gradient('120px',200,230,240,250,130,80,240);
      jdl.Index.Gradient('120px',240,190,150,245,230,240,250);
    },
    Main : function()
    {
      var tmp = window.onload;
      window.onload = function()
      {
        jdl.Index.Setup();
        if (tmp)
          tmp();
      }
    }
  };
}();

// Start things up.
jdl.Index.Main();

