/*global window, ActiveXObject, init, console*/
/*jslint white: true, browser: true, evil: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, strict: true, newcap: true, immed: true, indent: 2*/

'use strict';

/**
 * @author Brian
 */
var jackass = jackass || {
 /**
  * Cancels a link or form submission default event.  If the element passed is
  *  not a form or anchor, all child anchors within the parent will have their
  *  events bubbled into a canceling event.
  *
  * @param {Object} elm DOM element to have the link event cancelled.
  * @return {Boolean} false.
  */
  cancelLink : function (elm) {
    var tagName = elm.nodeName.toLowerCase(),
        event;

    if (tagName === 'a') {
      event = 'click';
    }

    else if (tagName === 'form') {
      event = 'submit';
    }

    if (event) {
      jackass.event.add(elm, event, function (e) {
        if (e.preventDefault) {
          e.preventDefault();
        }

        return false;
      });
    }

    else {
      jackass.event.add(elm, 'click', function (e) {
        var elm = jackass.getTarget(e);

        if (elm.nodeName.toLowerCase() !== 'a') {
          elm = jackass.getTarget(e);
        }

        if (e.preventDefault) {
          e.preventDefault();
        }

        return false;
      });
    }
  },

  event : {
    list : [],

   /**
    * Handles event attachment via the best method availalbe.
    *
    * @param {Object} elm Element to have the event attached to.
    * @param {String} event Event to trigger.  Options include all standard
    *         events, minus the "on" prefix (ex: "click", "dblclick", etc).
    *         Additionally, "mouseenter" and "mouseleave" are supported.
    * @param {Function} action Function to be executed when the given event is
    *         triggered.
    * @param {Boolean} capture true if the event should be registered as a
    *         capturing listener.  Defaults to false.
    * @note All events are added to the jackass.event.list array for access
    *        outside this function.
    */
    add : function (elm, event, action, capture) {
      capture = capture || false;

      var mouseEnter = function (action) {
        return function (e) {
          var target = e.relatedTarget;

          if ((this === target) || (jackass.isChildOf(target, this))) {
            return;
          }
			
          action.call(this, event);
        };
      };

      if (elm.addEventListener) {
        if (event === 'mouseenter') {
          action = mouseEnter(action);
          elm.addEventListener('mouseover', action, capture);
          event = 'mouseover';
        }

        else if (event === 'mouseleave') {
          action = mouseEnter(action);
          elm.addEventListener('mouseout', action, capture);
          event = 'mouseout';
        }

        else {
          elm.addEventListener(event, action, capture);
        }
      }

      else if (elm.attachEvent) {
        elm.attachEvent('on' + event, action);
      }

      else {
        elm['on' + event] = action;
      }

      jackass.event.list.push([elm, event, action]);
    },

   /**
    * Removes events attached to a given element.
    *
    * @param {Object} elm Element to have the event removed from.
    * @param {String} event Event to trigger.  Options include all standard
    *         events, minus the "on" prefix (ex: "click", "dblclick", etc).  If
    *         the events "mouseenter" and "mouseleave" are to be removed - you
    *         must specify their native events "mouseover" and "mouseout".
    * @param {Function} action Function to be removed from the given element and
    *         event.
    * @param {Boolean} capture true if the event was registered as a capturing
    *         listener.  Defaults to false.
    * @note Automatically removes the event from the jackass.event.list array.
    */
    remove : function (elm, event, action, capture) {
      capture = capture || false;

      var i = 0;

      if (event === 'mouseenter') {
        event = 'mouseover';
      }

      else if (event === 'mouseleave') {
        event = 'mouseout';
      }

      if (elm.removeEventListener) {
        elm.removeEventListener(event, action, capture);
      }

      else if (elm.detachEvent) {
        elm.detachEvent('on' + event, action);
      }

      else {
        elm['on' + event] = null;
      }

      for (i; i < jackass.event.list.length; i += 1) {
        if (jackass.event.list[i]) {
          if ((jackass.event.list[i]) &&
              (jackass.event.list[i][0] === elm) &&
              (jackass.event.list[i][1] === event) &&
              (jackass.event.list[i][2] === action)) {
            jackass.event.list.splice(i, 1);

            break;
          }
        }
      }
    },

   /**
    * Loops through all registered events (referencing the jackass.event.list
    *  array) and removes all events.  This should only be executed onunload to
    *  prevent documented IE6 memory leaks.
    */
    removeAll : function (elm) {
      elm = elm || document;

      var i = jackass.event.list.length - 1;

      for (i; i >= 0 ; i -= 1) {
        if (jackass.event.list[i]) {
          if ((jackass.event.list[i]) && ((jackass.event.list[i][0] === elm) || (elm === document))) {
            jackass.event.remove(jackass.event.list[i][0], jackass.event.list[i][1], jackass.event.list[i][2]);
          }
        }
      }
    }
  },

 /**
  * Looks for a given attribute with a specified value within the given
  *  element.
  *
  * @param {Object} elm Element to check for a given attribute.
  * @param {String} attribute Attribute being checked.
  * @param {String} value Value of the attribute specifically being checked.
  * @return {Boolean} true if the given attribute and value is found within the
  *          element.
  */
  hasAttribute : function (elm, attribute, value) {
    if (elm[attribute]) {
      return elm[attribute].match(new RegExp('(\\s|^)' + value + '(\\s|$)'));
    }
  },

 /**
  * Sugar function used to find if a given element has the 'className'
  *  attribute specified.
  *
  * @param {Object} elm Element to check for a given class name.
  * @param {String} className Class name being checked.
  */
  hasClass : function (elm, className) {
    return jackass.hasAttribute(elm, 'className', className);
  },

 /**
  * Add the specified class to the given element - but only if it does not
  *  already have the class.
  *
  * @param {Object} elm Element to apply the given class to.
  * @param {String} className Class name to be applied.
  */
  addClass : function (elm, className) {
    if (!jackass.hasClass(elm, className)) {
      elm.className = jackass.trim(elm.className + ' ' + className);
    }
  },

 /**
  * Removes the specified class from the given element.
  *
  * @param {Object} elm Element to remove the given class from.
  * @param {String} className Class name to be removed.
  */
  removeClass : function (elm, className) {
    if (jackass.hasClass(elm, className)) {
      elm.className = elm.className.replace(new RegExp('(\\s|^)' + className + '(\\s|$)'), ' ');
      elm.className = jackass.trim(elm.className);
    }
  },

 /**
  * Sugar function used to add or remove a class from a given element -
  *  depending on if it already has the class applied.
  *
  * @param {Object} elm Element to have the class toggled.
  * @param {String} className Class Name to be toggled.
  */
  toggleClass : function (elm, className) {
    if (!jackass.hasClass(elm, className)) {
      jackass.addClass(elm, className);
    }

    else {
      jackass.removeClass(elm, className);
    }
  },


 /**
  * Removes extra whitespace at the beginning or end of a given string.
  *
  * @param {String} string String of text that may have leading or trailing
  *         whitespace.
  * @return {String} String of text with leading or trailing whitespace
  *          removed.
  */
  trim : function (string) {
    string = string || '';

    return string.toString().replace(/^\s\s*/, '').replace(/\s\s*$/, '');
  },

 /**
  * Finds all elements with the given class name.  Optionally, a tag name can
  *  specified to further refine an element search.
  *
  * @param {String} className Class name to be searched for.
  * @param {Object} parent Parent element to begin the search from.  If no
  *         element is specified, the document root will be used.
  * @param {String} tag Optionally, you may specify a tag name to further
  *         filter.
  * @return {Array} Returns an array of elements matching the entered criteria.
  * @note Uses native getElementsByClassName if available.
  */
  getElementsByClassName : function (className, parent, tag) {
    var elementsWithClass = [],
        children = [],
        i = 0,
        j = 0;

    parent = parent || document;
    tag    = tag.toLowerCase() || '*';

    if ((tag === '*') && (document.getElementsByClassName)) {
      return parent.getElementsByClassName(className);
    }

    if (parent.getElementsByClassName) {
      children = parent.getElementsByClassName(className);

      if ((tag) && (children.length)) {
        for (i in children) {
          if ((children[i].tagName) && (children[i].tagName.toLowerCase() === tag)) {
            elementsWithClass[j] = children[i];
            j += 1;
          }
        }
      }

      else {
        elementsWithClass = children;
      }
    }

    else {
      children = parent.getElementsByTagName(tag);

      for (i in children) {
        if (jackass.hasClass(children[i], className)) {
          elementsWithClass[j] = children[i];
          j += 1;
        }
      }
    }

    return elementsWithClass;
  },

 /**
  * Checks all links from a given element parent for the attribute
  *  "rel="external"" and adds the attribute "target="_blank"" - as to avoid
  *  validation errors.
  *
  * @param {Object} elm Element to be searched for anchors with the rel
  *         attribute of "external".  If no element is specified, the document
  *         root will be searched.
  */
  externalLinks : function (elm) {
    elm = elm || document;

    var links = elm.getElementsByTagName('a'),
        i     = 0;

    for (i; i < links.length; i += 1) {
      if (/(?:^|\s)external(?:\s|$)/.test(links[i].rel)) {
        links[i].target = '_blank';
      }
    }
  },

	popup : function(url){
		popupWindow = window.open(
		 	url,'popUpWindow','height=450,width=460,left=10,top=10,resizable=yes,scrollbars=yes,toolbar=no,menubar=no,location=no,directories=no,status=yes')
	},

 /**
  * Initialization.  Executes the standard functions used.  If a
  *  global function of "init" is available, it will also be executed.
  */
  init : function () {
    var trailer = jackass.getElementsByClassName('trailer', document.getElementById('content'), 'li');
    	trailer = trailer[0].getElementsByTagName('a')[0];
    	jackass.cancelLink(trailer);
      jackass.event.add(trailer, 'click', function () {
        jackass.toggleClass(document.getElementById('popup'), 'active');
      });
    	
    	var	embed = jackass.getElementsByClassName('embed', document.getElementById('popup'), 'li');
    	embed = embed[0].getElementsByTagName('a')[0];
	
  	   var close   = jackass.getElementsByClassName('close', document.getElementById('popup'), 'li')[0];
  	 var	closeEmbed = jackass.getElementsByClassName('closeEmbed', document.getElementById('popup'), 'li')[0];

    var share   = jackass.getElementsByClassName('share', document.getElementById('share'), 'li')[0];

  	   jackass.event.add(close, 'click', function () {
  	       jackass.toggleClass(document.getElementById('popup'), 'active');
  	     });
  	 
  	 jackass.event.add(closeEmbed, 'click', function () {
  	 	jackass.toggleClass(document.getElementById('embed'), 'active');
  	     });
  	 
  	 jackass.event.add(embed, 'click', function (e) {
  	 	e.preventDefault();
  	 	jackass.toggleClass(document.getElementById('embed'), 'active');
  	     });
  	// 

	// var	email = jackass.getElementsByClassName('email', document.getElementById('content'), 'li');
	// email = email[0].getElementsByTagName('a')[0];
	// 	
	//   	jackass.event.add(email, 'click', function (e) {
	//   		e.preventDefault();
	//   		jackass.popup(email.href);
	//   	    });
	//   
    jackass.externalLinks();
  }
};

if (document.addEventListener) {
  document.addEventListener('DOMContentLoaded', jackass.init, false);
}

jackass.event.add(window, 'load', function () {
  if (!document.addEventListener) {
    jackass.init();
  }
});

jackass.event.add(window, 'unload', function () {
  jackass.event.removeAll();
});
