/******************************************************************************
 *
 *  smuFramework
 *  by Michael Richardson
 *  
 *  This framework is designed to host the various other scripts I want to make.
 *  It is basically a script loader with a few functions built in like a light-
 *  weight tooltip style popup and Ajax.         
 *  
 *  As a side effect of the Tip window, it also provides a uniform way to access
 *  the mouse location via window.smu.mouseX/Y.   
 *
 *  Target Browsers:
 *    High priority: 
 *      Internet Explorer 6, 7, and eventually 8.
 *      Firefox 2 and 3.
 *    Opera 9.27 and up.
 *    Nintendo Wii Internet Channel (Opera) 
 *    Sony PSP (NetFront)
 *    Sony PlayStation 3 (NetFront) 
 *    Safari 3.1 and up (Windows only as I have no Mac.)    
 *     
 ******************************************************************************/


function smuMake() {

  window["smu"] = new Array();
  
  window.smu["loaded"] = new Array();

  /****************************************************************************
   * addEventListener                                                         *
   ****************************************************************************/     

    window.smu["addEventListener"] = function (element, eventName, handler) {
      if (element.addEventListener) {
        element.addEventListener(eventName, handler, false);
      } else if (element.attachEvent) {
        element.attachEvent("on"+eventName, handler);
      } else {
        window.smu.addError("addEventListener", "Element has no method for adding event handler.");
      }
    }

  /****************************************************************************
   * Ajax                                                                     *
   ****************************************************************************/

    window.smu["ajax"] = function (url, callbackFunction){
      var request = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP.3.0");
      
      request.open("GET", url, true);
      request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); 
      
      request.onreadystatechange = function(){
        
        if (request.readyState == 4) {
          if (request.status == 200) {  
            if (request.responseText){
              callbackFunction(request.responseText);
            }
          } else {
            window.smu.addError("ajax", "Request errored out with code " + request.status);
          }
        }
      }
      request.send(null);
    }

  /****************************************************************************
   * Cookies                                                                  *
   ****************************************************************************/
  
    window.smu["cookie"] = new Array();

    window.smu.cookie["set"] = function (name, value, life) {
      var now = new Date();
      var expire = new Date();
      expire.setTime(now.getTime() + 3600000 * life);
      document.cookie = name + "=" + escape(value) + "; expires = " + expire.toGMTString();
    }

    window.smu.cookie["erase"] = function (name) {
      window.smu.cookie.set(name, "", -1);
    }
    
    window.smu.cookie["get"] = function (name) {

      // Quickly borrowed from http://www.quirksmode.org/js/cookies.html
    
    	var nameEQ = name + "=";
    	var ca = document.cookie.split(';');
    	for(var i=0;i < ca.length;i++) {
    		var c = ca[i];
    		while (c.charAt(0)==' ') c = c.substring(1,c.length);
    		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    	}
    	return null;

    }
    
  /****************************************************************************
   * Error List                                                               *
   ****************************************************************************/

    window.smu["errors"] = new Array();

    window.smu["addError"] = function (source, message) {
      var error = new Array();
      error["source"] = source;
      error["message"] = message;
      window.smu.errors.push(error);
    }  
  
  /****************************************************************************
   * Google Search
   ****************************************************************************/
   
    window.smu["google"] = new Array();
    window.smu.google["apikey"] = "";
    window.smu.google["elementID"] = "";
    
    window.smu.google["activate"] = function (element) {
      google.load("search", "1", {"language" : "en"});
      google.setOnLoadCallback(window.smu.google.processLoad);
      window.smu.google.elementID = element;
    }
        
    window.smu.google["processLoad"] = function(e) {
        var searchControl = new google.search.SearchControl();
        var options = new GsearcherOptions();
        options.setExpandMode(GSearchControl.EXPAND_MODE_OPEN);
        
        var drawOptions = new GdrawOptions();
        drawOptions.setDrawMode(GSearchControl.DRAW_MODE_TABBED);
        
      
      /*
      
        // This is the basic sample code.
        var localSearch = new google.search.LocalSearch();
        
        searchControl.addSearcher(localSearch);
        searchControl.addSearcher(new google.search.WebSearch());
        searchControl.addSearcher(new google.search.VideoSearch());
        searchControl.addSearcher(new google.search.BlogSearch());
        
        localSearch.setCenterPoint("Philadelphia, PA");
        
      */
      
        // Build search for just this site
        var siteSearch = new google.search.WebSearch();
        siteSearch.setUserDefinedLabel("UltimateMK.com");
        siteSearch.setSiteRestriction("ultimatemk.com/");
        searchControl.addSearcher(siteSearch, options);
      
        var vidSearch = new GvideoSearch();
        //vidSearch.setUserDefinedLabel("YouTube");
        //vidSearch.setSiteRestriction("youtube.com/");
        searchControl.addSearcher(vidSearch, options);
      
        searchControl.draw(document.getElementById(window.smu.google.elementID), drawOptions);
        window.smu.google["searchControl"] = searchControl;
    }
              
  /****************************************************************************
   * Include
   ****************************************************************************/
   
    window.smu["include"] = function(path) {
      var head = document.getElementsByTagName("head")[0];
      
      var script = document.createElement("script");
      script.setAttribute("src", path);
      script.setAttribute("type", "text/javascript");
      
      head.appendChild(script);
    }
        
  /****************************************************************************
   * junk
   ****************************************************************************/
   
    window.smu["junk"] = function () {
      var d = new Date();
      return "" + d.getFullYear() + d.getMonth() + d.getDate() + d.getHours() + d.getMinutes() + d.getSeconds() + d.getMilliseconds();
    }     
  
  /****************************************************************************
   * Mouse Capturing                                                          *
   ****************************************************************************/     

    window.smu["mouseX"] = 0;
    window.smu["mouseY"] = 0;

    window.smu["updateMouse"] = function(e) {
      if (!e) var e = window.event;
      
      if (e.clientX) {
        if (document.documentElement) {
          window.smu.mouseX = e.clientX + document.documentElement.scrollLeft;
          window.smu.mouseY = e.clientY + document.documentElement.scrollTop;
        } else {
          window.smu.mouseX = e.clientX + document.body.scrollLeft;
          window.smu.mouseY = e.clientY + document.body.scrollTop;
        }
      } else if (e.pageX) {
        window.smu.mouseX = e.pageX + window.pageXOffset;
        window.smu.mouseY = e.pageY + window.pageYOffset;
      }
      
      
    }

    window.smu.addEventListener(document, "mousemove", window.smu.updateMouse);

  /****************************************************************************
   * Module Functions                                                         *
   ****************************************************************************/

    window.smu["module"] = new Array();
    window.smu.module["events"] = new Array();
    
    window.smu.module["addEvent"] = function (module, event, handler) {
      
      // Make sure there is a container for the specified module.
      if (!window.smu.module.events[module]) window.smu.module.events[module] = new Array();
      
      // Make sure there is a container for the event for this module.
      if (!window.smu.module.events[module][event]) window.smu.module.events[module][event] = new Array();
      
      // Store the event handler here.
      window.smu.module.events[module][event].push(handler);
      
    }
    
    window.smu.module["fireEvent"] = function (module, event) {
      if (window.smu.module.events[module][event]) {
        for (var i = 0; i < window.smu.module.events[module][event].length; i++) {
          window.smu.module.events[module][event][i]();
        }
      }
    }
    
    // Gets the module.  The module is not loaded when this function finishes!
    window.smu.module["get"] = function(modName) {
      var head = document.getElementsByTagName("head")[0];
      
      var script = document.createElement("script");
      script.setAttribute("src", modName+".js");
      script.setAttribute("type", "text/javascript");
      
      head.appendChild(script);
    }

    window.smu.module["onLoad"] = function(modName) {
      window.smu.loaded[modName] = true;
      window.smu.module.fireEvent(modName, "load");
    }

  /****************************************************************************
   * Skids - Floating Windows                                                 *
   ****************************************************************************/     

    window.smu["skid"] = new Array();
    window.smu.skid["currentElement"] = null;
    window.smu.skid["currentResizeElement"] = null;
    
    window.smu.skid["offsetX"] = 0;
    window.smu.skid["offsetY"] = 0;
    window.smu.skid["zIndex"] = 1;
    window.smu.skid["resizeOffsetX"] = 6;
    window.smu.skid["resizeOffsetY"] = 6;
    
    window.smu.skid["fetch"] = function(skidID, url) {
      window.smu.ajax(url, 
        function (text) {
          document.getElementById(skidID+"_content").innerHTML = text;
        }
      );
    }
    
    window.smu.skid["getFromElement"] = function(skidID, element) {
          document.getElementById(skidID+"_content").innerHTML = document.getElementByID(element).innerHTML;
    }
    
    window.smu.skid["grab"] = function(skidID) {
      window.smu.skid.currentElement = document.getElementById(skidID);
      if (window.smu.skid.currentElement) {
        window.smu.skid.offsetX = window.smu.mouseX - parseInt(window.smu.skid.currentElement.style.left);
        window.smu.skid.offsetY = window.smu.mouseY - parseInt(window.smu.skid.currentElement.style.top);
        window.smu.skid.currentElement.style.zIndex = window.smu.skid.zIndex;
        window.smu.skid.zIndex++;
        
        // Store the info for this element in the cookies.
        window.smu.cookie.set(skidID+"isset", "true", 999);
        window.smu.cookie.set(skidID+"x", window.smu.skid.currentElement.style.left, 999);
        window.smu.cookie.set(skidID+"y", window.smu.skid.currentElement.style.top, 999);
      }      
    }
    
    window.smu.skid["release"] = function() {
      window.smu.skid.currentElement = null;
    }
    
    window.smu.skid["byName"] = new Array();
    
    window.smu.skid["make"] = function(name, title, resizable) {
    
      /*
      var skidID = "smuSkid" + window.smu.skid.nextID;
      window.smu.skid.nextID++;
      */
      
      var skidID = name;
      
      var skid = document.createElement("div");
      skid.setAttribute("id", skidID);
      skid.style.position = "absolute";
      skid.style.width = "400px";
      skid.style.top = "10px";
      skid.style.left = "10px";
      skid.style.height = "400px";
      skid.className="skid";

      // Check for cookies defining this skids location.
      if (window.smu.cookie.get(skidID+"isset") == "true") {
        skid.style.left = parseInt(window.smu.cookie.get(skidID+"x")) + "px";
        skid.style.top = parseInt(window.smu.cookie.get(skidID+"y")) + "px";
        skid.style.height = parseInt(window.smu.cookie.get(skidID+"height")) + "px";
        skid.style.width = parseInt(window.smu.cookie.get(skidID+"width")) + "px";
      }

      var titlebar = document.createElement("div");
      titlebar.setAttribute("id", skidID + "_title");
      titlebar.className = "skidTitle";      

      var max = document.createElement("span");
      max.innerHTML = " + ";
      max.setAttribute("id", skidID + "_maximize");
      titlebar.appendChild(max);

      var min = document.createElement("span");
      min.innerHTML = " - ";
      min.setAttribute("id", skidID + "_minimize");
      titlebar.appendChild(min);
      
      titlebar.appendChild(document.createTextNode(title));
      
      window.smu.addEventListener(max, 'mousedown',
        function(e) {
          document.getElementById(skidID + "_content").style.display="block";
          document.getElementById(skidID + "_grabber").style.display="block";
          window.smu.skid.byName[name].element.style.height = window.smu.skid.byName[name].visibleHeight;
        }
      );
      
      window.smu.addEventListener(min, 'mousedown',
        function(e) {
          window.smu.skid.byName[name].visibleHeight = window.smu.skid.byName[name].element.style.height;
          window.smu.skid.byName[name].element.style.height = "20px";
          document.getElementById(skidID + "_content").style.display = "none";
          document.getElementById(skidID + "_grabber").style.display = "none";
        }
      );
      
      window.smu.addEventListener(titlebar, 'mousedown', 
        function(e){
          // Grab this window.
          window.smu.skid.grab(skidID);
        }
      );
      
      window.smu.addEventListener(document, 'mouseup',
        function(e) {
          window.smu.skid.release();
        }
      );
      
      skid.appendChild(titlebar);

      var contentarea = document.createElement("div");
      contentarea.setAttribute("id", skidID + "_content");
      contentarea.className = "skidContent";
      contentarea.style.color = "#000000";
      contentarea.style.height = (parseInt(skid.style.height) - 49) + "px";
      skid.appendChild(contentarea);
      
      var grabber = document.createElement("div");
      grabber.setAttribute("id", skidID + "_grabber");
      grabber.style.width = "23px";
      grabber.style.height = "23px";
      grabber.style.backgroundColor = "#f0f0f0";
      grabber.style.position = "absolute";
      grabber.style.top = (parseInt(skid.style.height) - 20) + "px";
      grabber.style.left = (parseInt(skid.style.width) - 20) + "px";
      
      window.smu.addEventListener(grabber, 'mouseover',
        function(e) {
          grabber.style.cursor = "se-resize";
        }
      );
      
      window.smu.addEventListener(grabber, 'mouseout',
        function(e) {
          grabber.style.cursor = "auto";
        }
      );
      
      window.smu.addEventListener(grabber, 'mousedown',
        function(e) {
          window.smu.skid.resizeStart(skidID);
        }
      );
      
      window.smu.addEventListener(document, 'mouseup',
        function(e) {
          window.smu.skid.resizeEnd(skidID);
        }
      )
      
      skid.appendChild(grabber);
      
      document.body.appendChild(skid);

      var entry = new Array();
      entry["element"] = document.getElementById(skidID);
      entry["content"] = document.getElementById(skidID + "_content");
      entry["title"] = document.getElementById(skidID + "_title");
      entry["resizable"] = resizable;
      entry["visibleHeight"] = entry.element.style.height;
      
      entry["fetch"] = function (url) {
        window.smu.skid.fetch(skidID, url);
      }
      entry["getFromElement"] = function (element) {
        document.getElementById(skidID + "_content").innerHTML = document.getElementById(element).innerHTML;
      }
      window.smu.skid.byName[name] = entry;
      return skidID;
    }
    
    window.smu.skid["resizeChildren"] = function (skidID) {

      document.getElementById(skidID + "_content").style.height = (parseInt(document.getElementById(skidID).style.height) - 49) + "px";
      document.getElementById(skidID + "_grabber").style.top = (parseInt(document.getElementById(skidID).style.height) - 20) + "px";
      document.getElementById(skidID + "_grabber").style.left = (parseInt(document.getElementById(skidID).style.width) - 20) + "px";
    }
    
    window.smu.skid["resizeStart"] = function (skidID) {
      window.smu.skid.currentResizeElement = document.getElementById(skidID);
    }
    
    window.smu.skid["resizeEnd"] = function (skidID) {
      window.smu.cookie.set(skidID+"isset", "true", 999);
      window.smu.cookie.set(skidID+"width", document.getElementById(skidID).style.width,999);
      window.smu.cookie.set(skidID+"height", document.getElementById(skidID).style.height,999);
      window.smu.skid.currentResizeElement = null;
    }
    
    window.smu.skid["updateSkid"] = function(e) {
      if (window.smu.skid.currentElement) {
        window.smu.skid.currentElement.style.top = (window.smu.mouseY - window.smu.skid.offsetY) + "px";
        window.smu.skid.currentElement.style.left = (window.smu.mouseX - window.smu.skid.offsetX) + "px";
      }

      if (window.smu.skid.currentResizeElement) {
        window.smu.skid.currentResizeElement.style.height = (window.smu.mouseY - parseInt(window.smu.skid.currentResizeElement.style.top)) + "px";
        window.smu.skid.currentResizeElement.style.width = (window.smu.mouseX - parseInt(window.smu.skid.currentResizeElement.style.left)) + "px";
        if (parseInt(window.smu.skid.currentResizeElement.style.width) < 100) window.smu.skid.currentResizeElement.style.width = "100px";
        if (parseInt(window.smu.skid.currentResizeElement.style.height) < 100) window.smu.skid.currentResizeElement.style.height = "100px";
        window.smu.skid.resizeChildren(window.smu.skid.currentResizeElement.getAttribute("id"));
      }      
      
    }

    window.smu.addEventListener(document, "mousemove", window.smu.skid.updateSkid);
    
    window.smu.skid["nextID"] = 1;
    
  /****************************************************************************
   * System Message                                                           *
   ****************************************************************************/

    window.smu["systemMessage"] = new Array();
    
    window.smu.systemMessage["text"] = "";
    window.smu.systemMessage["color"] = 255;
    
    var messageBox = document.createElement("div");
    messageBox.setAttribute("id", "smuSystemMessage");
    messageBox.style.position = "absolute";
    
  /****************************************************************************
   * Tip Window                                                               *
   ****************************************************************************/
  
    var tip = document.createElement("div");
    tip.setAttribute("id", "smuTip");
    tip.style.position = "absolute";
    tip.style.top = "0px";
    tip.style.minWidth = "100px";
    tip.style.maxWidth = "600px";
    tip.style.left = "0px";
    tip.style.backgroundColor = "#e0e0e0";
    tip.style.border = "1px solid #000000";
    tip.style.color = "#000000";
    tip.style.zIndex = "999999";
    tip.style.display = "none";
    tip.className = "smuTip";
    
    var tiptop = document.createElement("div");
    tiptop.setAttribute("id", "smuTipTitle");
    tiptop.style.width = "100%";
    tiptop.style.backgroundColor = "#000000";
    tiptop.style.color = "#FFFFFF";
    tiptop.innerHTML = "info";
    tip.appendChild(tiptop);
  
    var text = document.createElement("div");
    text.style.padding ="5px";
    text.setAttribute("id", "smuTipText");
    text.className = "smuTipText";
    tip.appendChild(text);
    
    document.body.appendChild(tip);
    window.smu.tip = new Array();
    window.smu.tip["element"] = document.getElementById("smuTip");
    window.smu.tip["text"] = document.getElementById("smuTipText");
    window.smu.tip["title"] = document.getElementById("smuTipTitle");
    
    window.smu.tip["show"] = function (text, title) {
    
      if (title==null) {
        window.smu.tip.title.style.display = "none";
      } else {
        window.smu.tip.title.style.display = "block";
        window.smu.tip.title.innerHTML = title;
      }
    
      window.smu.tip.text.innerHTML = text;
      window.smu.tip.element.style.display = "block";
      
      // This is necessary because of how IE handles 100% wide divs inside divs with minWidth set.
      window.smu.tip.title.style.width = window.smu.tip.element.style.width;
    }
    
    window.smu.tip["hide"] = function() {
      window.smu.tip.element.style.display = "none";
    }
    
    window.smu.tip["register"] = function (id, title, message) {
    
      window.smu.addEventListener(document.getElementById(id), "mouseover", 
        function () {
          window.smu.tip.show(message, title);
        }
      );
      
      window.smu.addEventListener(document.getElementById(id), "mouseout",
        function () {
          window.smu.tip.hide();
        }
      );
    
    }
    
    window.smu.tip["updateLocation"] = function() {  // Attaches to document's mousemove event.
      var x = window.smu.mouseX + window.smu.tip.offsetX;
      var y = window.smu.mouseY + window.smu.tip.offsetY;
      
      if (x < 0) x = 0;
      if (parseInt(window.smu.tip.element.style.width) + x + 10 > document.body.clientWidth) x = document.body.clientWidth - parseInt(window.smu.tip.element.style.width) - 10;
      window.smu.tip.element.style.left = x + "px";
  
      if (y < 0) y = 0;
      window.smu.tip.element.style.top = y + "px";
    }
    
    window.smu.tip["offsetX"] = 15;
    window.smu.tip["offsetY"] = 10;
    
    // Update the tooltip location:
    window.smu.addEventListener(document, "mousemove", window.smu.tip.updateLocation);
    
  /****************************************************************************
   * Finalize smuFramework loading                                            *
   ****************************************************************************/
    
    window.smu.loaded["smuFramework"] = true;
 
             
}
