﻿

// JavaScript Document
//SitePoint.Simply.JavaScript.Jun.2007.pdf 403  (The Complete Library)

var Core = {};
// W3C DOM 2 Events model
if (document.addEventListener)
{
  Core.addEventListener = function(target, type, listener)
  {
    target.addEventListener(type, listener, false);
  };
  
  Core.removeEventListener = function(target, type, listener)
  {
    target.removeEventListener(type, listener, false);
  };
  
  Core.preventDefault = function(event)  
  /*397 In order to prevent the default action associated with an event in IE,
    we simply set the event object’s returnValue property to false. Similarly, 
	in order to stop the propagation of an event in IE, we set its cancelBubble 
	property to true. And that’s all these methods need to do.*/
  {
    event.preventDefault();
  };
  
  Core.stopPropagation = function(event)
  {
    event.stopPropagation();
  };
}


// Internet Explorer Events model
else if (document.attachEvent)
{
  Core.addEventListener = function(target, type, listener)
  {
    // prevent adding the same listener twice, since DOM 2
    // Events ignores duplicates like this
    if (Core._findListener(target, type, listener) != -1)
      return;
    // listener2 calls listener as a method of target in one of
    // two ways, depending on what this version of IE supports,
    // and passes it the global event object as an argument
    var listener2 = function()
    {
      var event = window.event;
      if (Function.prototype.call)
      {
        listener.call(target, event);
      }
      else
      {
        target._currentListener = listener;
        target._currentListener(event)
        target._currentListener = null;
      }
    };
    // add listener2 using IE's attachEvent method
    target.attachEvent("on" + type, listener2);
    // create an object describing this listener so we can
    // clean it up later
    var listenerRecord =
    {
      target: target,
	  type: type,
      listener: listener,
      listener2: listener2
    };
    // get a reference to the window object containing target
    var targetDocument = target.document || target;
    var targetWindow = targetDocument.parentWindow;
    // create a unique ID for this listener
    var listenerId = "l" + Core._listenerCounter++;
    // store a record of this listener in the window object
    if (!targetWindow._allListeners)
      targetWindow._allListeners = {};
    targetWindow._allListeners[listenerId] = listenerRecord;
    // store this listener's ID in target
    if (!target._listeners) target._listeners = [];
    target._listeners[target._listeners.length] = listenerId;
    // set up Core._removeAllListeners to clean up all
    // listeners on unload
    if (!targetWindow._unloadListenerAdded)
    {
      targetWindow._unloadListenerAdded = true;
      targetWindow.attachEvent(
          "onunload", Core._removeAllListeners);
    }
  };
  
  
  Core.removeEventListener = function(target, type, listener)
  {
    // find out if the listener was actually added to target
    var listenerIndex = Core._findListener(
        target, type, listener);
    if (listenerIndex == -1) return;
    // get a reference to the window object containing target
    var targetDocument = target.document || target;
    var targetWindow = targetDocument.parentWindow;
    // obtain the record of the listener from the window object
    var listenerId = target._listeners[listenerIndex];
	var listenerRecord =
        targetWindow._allListeners[listenerId];
    // remove the listener, and remove its ID from target
    target.detachEvent("on" + type, listenerRecord.listener2);
    target._listeners.splice(listenerIndex, 1);
    // remove the record of the listener from the window object
    delete targetWindow._allListeners[listenerId];
  };
  
  Core.preventDefault = function(event)
  {
    event.returnValue = false;
  };
  
  Core.stopPropagation = function(event)
  {
    event.cancelBubble = true;
  };
  
  Core._findListener = function(target, type, listener)
  {
    // get the array of listener IDs added to target
    var listeners = target._listeners;
    if (!listeners) return -1;
    // get a reference to the window object containing target
    var targetDocument = target.document || target;
    var targetWindow = targetDocument.parentWindow;
    // searching backward (to speed up onunload processing),
    // find the listener
    for (var i = listeners.length - 1; i >= 0; i--)
    {
      // get the listener's ID from target
      var listenerId = listeners[i];
      // get the record of the listener from the window object
      var listenerRecord =
          targetWindow._allListeners[listenerId];
      // compare type and listener with the retrieved record
      if (listenerRecord.type == type && listenerRecord.listener == listener)
      {
        return i;
      }
    }
    return -1;
  };
  

  Core._removeAllListeners = function()
  {
    var targetWindow = this;
    for (id in targetWindow._allListeners)
    {
      var listenerRecord = targetWindow._allListeners[id];
      listenerRecord.target.detachEvent(
          "on" + listenerRecord.type, listenerRecord.listener2);
      delete targetWindow._allListeners[id];
    }
  };
  Core._listenerCounter = 0;
}



Core.addClass = function(target, theClass)
{
  if (!Core.hasClass(target, theClass))
  {
    if (target.className == "")
    {
      target.className = theClass;
    }
    else
    {
      target.className += " " + theClass;
    }
  }
};

// 98 Finding Elements by Class Name begin

Core.getElementsByClass = function(theClass)
{
  //1. Look at each element in the document begin
  var elementArray = [];
  if (document.all)
  {
    elementArray = document.all;
  }
  else
  {
    elementArray = document.getElementsByTagName("*");
  }
  //Look at each element in the document end
  
  var matchedArray = [];   //our group of elements
  
  //the class we are looking for.
  var pattern = new RegExp("(^| )" + theClass + "( |$)");
  
  //For each element, perform a check that compares its class against the one we’re looking for.
  //If the classes match, add the element to our group of elements.
  for (var i = 0; i < elementArray.length; i++)
  {
    if (pattern.test(elementArray[i].className))
    {
      matchedArray[matchedArray.length] = elementArray[i];
    }
  }
  return matchedArray;
};
// 103 Finding Elements by Class Name end

Core.hasClass = function(target, theClass)
{
  var pattern = new RegExp("(^| )" + theClass + "( |$)");
  if (pattern.test(target.className))
  {
    return true;
  }
  return false;
};


Core.removeClass = function(target, theClass)
{
  var pattern = new RegExp("(^| )" + theClass + "( |$)");
  target.className = target.className.replace(pattern, "$1");
  target.className = target.className.replace(/ $/, "");
};


Core.getComputedStyle = function(element, styleProperty)
{
var computedStyle = null;
  if (typeof element.currentStyle != "undefined")
  {
    computedStyle = element.currentStyle;
  }
  else
  {
    computedStyle =
        document.defaultView.getComputedStyle(element, null);
  }
  return computedStyle[styleProperty];
};


Core.start = function(runnable)
{
  Core.addEventListener(window, "load", runnable.init);
};
