/*
 * Create the Namespace Manager that we'll use to
 * make creating namespaces a little easier.
 */
if (typeof Namespace == 'undefined') var Namespace = {};
if (!Namespace.Manager) Namespace.Manager = {};

Namespace.Manager = {
  Register:function(namespace){
    namespace = namespace.split('.');

    if (!window[namespace[0]]) window[namespace[0]] = {};

    var strFullNamespace = namespace[0];
    for (var i = 1; i < namespace.length; i++) {
      strFullNamespace += "." + namespace[i];
      eval("if (!window." + strFullNamespace + ")window." + strFullNamespace + "={};");
    }
  }
};

// Register our Namespace
Namespace.Manager.Register("NestedMedia.Utility.Class");


/*
 * Here we are creating the NestedMedia.Utility.Class.EventManager class
 * You can get the event related functions in this class
 */
NestedMedia.Utility.Class.NMEventManager = function(clientID,class_key,userHost) {
var garbagelist = [];

var base_url = "http://svcs.nestedmedia.com/nmjs/"; // "http://localhost/nmjs/"

var debug = 0; // set to 0 to turn off jsonp debughandler callback from jsmsg.php, 1 to turn on

this.debugHandler = function(msg) {
  alert(msg);
  return;
}

function generateParams(target,event){
  // grab timestamp for this click event
  var d = new Date();

  //code for getting the cookieid from cookies
  var cookieid = (typeof(ObjNMCookieHandler) != "undefined") ? ObjNMCookieHandler.getCookieValue('cookieid') : '';
  return {'event':event,
          'url':location.href,
          'referrer':document.referrer,
          'target':target,
          'clientid':clientID,
          'cookieid':cookieid,
          'adid':adID,
          'browsertime':d,
          'month':d.getMonth(),
          'day':d.getDay(),
          'hour':d.getHours(),
          'browsername':navigator.appName,
          'browserversion':navigator.appVersion,
          'platform':navigator.platform
          };
}

function send_msg(data,debug){
  // remove any previous script tag to avoid memory consumption
  if(garbagelist.length > 0){
    document.body.removeChild(garbagelist[0]);

    // Remove any old script tags.
    var script;
    while (script = document.getElementById('JSONP')) {
      script.parentNode.removeChild(script);
      // Browsers won't garbage collect this object.
      // So empty it to avoid a major memory leak.
      for (var prop in script) {
        delete script[prop];
      }
    }
    // reset the garbage collection array
    garbagelist.splice(1,0);
  }

  // send msg to producer
  var url = base_url+'jsmsgr.php?event='+data.event+ 
                  '&url='+data.url+
                  '&referrer='+data.referrer+
                  '&target='+data.target+
                  '&clientid='+data.clientid+
                  '&cookieid='+data.cookieid+
                  '&adid='+data.adid+
                  '&browsertime='+data.browsertime+
                  '&month='+data.month+
                  '&day='+data.day+
                  '&hour='+data.hour+
                  '&browsername='+data.browsername+
                  '&browserversion='+data.browserversion+
                  '&platform='+data.platform+
                  '&debug='+debug;
  var js = document.createElement("script");
  js.id = 'JSONP';
  js.setAttribute("src",url+"&CacheBuster="+Math.random());
  js.setAttribute("type","text/javascript");

  // add element to scriptlist for garbage removal later
  garbagelist[0] = js;
  // write the jsonp script tag
  document.body.appendChild(js);  

  js.text = "";
}

/**
 * handleLoad event handler
 */
this.handleLoad = function(){
  // write jsonp script to send message
  var data = generateParams('','load')
  send_msg(data,debug);
}

/**
 * onclick event handler
 */
function handleClick(e) {

  // find target anchor tag
  var el;
  if (window.event && window.event.srcElement)
    el = window.event.srcElement;
  if (e && e.target)
    el = e.target;
  if (!el)
    return;

  // find link href
  while (el.nodeName.toLowerCase() != 'a' &&
      el.nodeName.toLowerCase() != 'body')
    el = el.parentNode;
  if (el.nodeName.toLowerCase() == 'body')
    return;

  // write jsonp script to send message
  var data = generateParams(el.href,'mouseclick');
  send_msg(data,debug);
}

/**
 * mouseover event handler
 */
function handleMouseOver(e) {
  var el;
  if (window.event && window.event.srcElement)
    el = window.event.srcElement;
  if (e && e.target)
    el = e.target;
  if (!el)
    return;

  while (el.nodeName.toLowerCase() != 'a' &&
      el.nodeName.toLowerCase() != 'body')
    el = el.parentNode;
  if (el.nodeName.toLowerCase() == 'body')
    return;

  var data = generateParams(el.href,'mouseover');
  send_msg(data,debug);
}

/**
 * mouseout event handler
 */
function handleMouseOut(e) {
  var el;
  if (window.event && window.event.srcElement)
    el = window.event.srcElement;
  if (e && e.target)
    el = e.target;
  if (!el)
    return;

  while (el.nodeName.toLowerCase() != 'a' &&
      el.nodeName.toLowerCase() != 'body')
    el = el.parentNode;
  if (el.nodeName.toLowerCase() == 'body')
    return;

  var data = generateParams(el.href,'mouseout');
  send_msg(data,debug);
}

/**
 * cross-browser event handling for IE5+, NS6 and Mozilla
 * By Scott Andrew
 */
//This addEvent function we are using for external class use
this.addEvent = function(elm, evType, fn, useCapture) {
  if (elm.addEventListener) { // Mozilla, Netscape, Firefox
    elm.addEventListener(evType, fn, useCapture);
    return true;
  } else if (elm.attachEvent) {  // IE5 +
    var r = elm.attachEvent('on' + evType, fn);
    return r;
  } else {
    elm['on' + evType] = fn;
  }
}

/**
 * Install listeners
 */
this.addListeners = function() {
  if (!document.getElementById)
    return;

  var all_links = document.getElementsByTagName('a');
  var ObjNMEventManager = new NestedMedia.Utility.Class.NMEventManager(clientID,class_key,usrHost);

  for (var i = 0; i < all_links.length; i++) {
    if(class_key){
      if (all_links[i].className && (' ' + all_links[i].className + ' ').indexOf(' ' + class_key + ' ') != -1) {
        ObjNMEventManager.addEvent(all_links[i], 'click', handleClick, false);
        ObjNMEventManager.addEvent(all_links[i], 'mouseover', handleMouseOver, false);
        //addEvent(all_links[i], 'mouseout', handleMouseOut, false);
      }
    } else { //if(all_links[i].href.startsWith('http://') && !all_links[i].href.match(usrHost)){
      ObjNMEventManager.addEvent(all_links[i], 'click', handleClick, false);
      ObjNMEventManager.addEvent(all_links[i], 'mouseover', handleMouseOver, false);
      //addEvent(all_links[i], 'mouseout', handleMouseOut, false);
    }
  }
}

/*
 * Using the AddJsFile function we can add the javascript file dynamically from HTML
 */
  function AddJsFile(file) {
    var script  = document.createElement('script');
    script.src  = file;
    script.type = 'text/javascript';
    //script.defer = true;

    document.getElementsByTagName('head').item(0).appendChild(script);
  }

/*
 * Using the RemoveJsCssFile function we can remove the javascript or css file dynamically from HTML
 */
  function RemoveJsCssFile(filename, filetype) {
    var targetelement = (filetype=="js") ? "script" : (filetype=="css") ? "link" : "none" //determine element type to create nodelist from
    var targetattr = (filetype=="js") ? "src" : (filetype=="css") ? "href" : "none" //determine corresponding attribute to test for
    var allsuspects = document.getElementsByTagName(targetelement)
    for (var i = allsuspects.length; i >= 0; i--){ //search backwards within nodelist for matching elements to remove
      if (allsuspects[i] && allsuspects[i].getAttribute(targetattr)!= null && allsuspects[i].getAttribute(targetattr).indexOf(filename)!=-1)
        allsuspects[i].parentNode.removeChild(allsuspects[i]) //remove element by calling parentNode.removeChild()
    }
  }

/*
 * This is common jsonp function for making the jsonpRequest
 */

function jsonpRequest(url, removescript, callback, name, query){
    if (url.indexOf("?") > -1)
        url += "&jsonp="
    else
        url += name + "&";
    if (query)
        url += encodeURIComponent(query) + "&";
    url += new Date().getTime().toString(); // prevent caching

    var script = document.createElement("script");
    script.setAttribute("src", url + "&CacheBuster=" + Math.random());
    script.setAttribute("type","text/javascript");
    document.body.appendChild(script);

   
    // Remove any old script tags.
   
    var script;
    while (script = document.getElementById('JSONP')) {
      script.parentNode.removeChild(script);
      // Browsers won't garbage collect this object.
      // So empty it to avoid a major memory leak.
      /*
      for (var prop in script) {
        delete script[prop];
      }
      */
    }
//alert("Here we are checking the dyanmically added script status, Status will be null: "+ script);

}


/*
 * gettting the Random UUID as data variable and uuid saving into cookies.
 */
this.get_cookieid = function(UUID) {
 // alert("I got cookie_id(uuid) in cookies"+UUID);

  if (!UUID) { //if uuid not present then we are creating or saving the cookies
    //alert("I did not got cookie_id(uuid) in cookies"+UUID);
/*
 * Making the jsonp request and fetching the random uuid
 * through this call we are saving uuid as cookieid in browser cookies
 */
    jsonpRequest(base_url+'getuuid.php?jsonp=mycallback&name=test');
   }
}

/**
 * authenticate the calling usr/host
 */
this.authenticate = function(client) {
  // 1) need cookie check here for credentials caching
/*
 * here we are making the jsonp request and fetching the cookieid from browser cookies
 * This base_url will call the get_cookieid function in return function.
 */
  jsonpRequest(base_url+'getcookies.php?jsonp=mycallback&name=test');


  // 2) if no session cookie, authenticate from db (simulated here)

  // client authentication db proxy - to be replaced by db lookup through server-side script include
  var client_arr = new Array(['123456','localhost'],['654321','projectwordhatch.com'],['a221ece3-3765-483c-ab8a-e087ff7cde28','30ninjas.com'],['425955c2-428b-4094-8e99-6f338a5fbdc0','hellomovies.com'],['96ae44e0-4046-490c-ad26-b19275a850a3','videolectures.net'],['96ae44e0-4046-490c-ad26-b19275a850a4','wrapnatural.com']); //['96ae44e0-4046-490c-ad26-b19275a850a3','videolectures.net'],

  // 3) compare client side credentials with user list from db, match the registered host to the calling host
  for(i=0; i<client_arr.length; i++){
    if(client_arr[i][0] == client && location.hostname.match(client_arr[i][1])){
      return client_arr[i][1];
    }
  }
  return 0;
}

/**
 *  protype startsWith function
 */
String.prototype.startsWith = function(str)
{return (this.match("^"+str)==str)}

/**
 * prototype cleanString function to help prevent cross-site scripting attacks
 * -- use on all client configuration variables
 */
this.cleanString = function(str) {
  str = unescape( str.toString() );
  str = str.replace(/</g, '&lt;');
  str = str.replace(/>/g, '&gt;');
  return str;
}
}

/************************ main loop **************************/

// get user ID from client side config variable
var clientID = (typeof(window.NM_SmartSite_ID) != "undefined") ? window.NM_SmartSite_ID : '';
var adID = (typeof(window.NM_SmartSite_AdID) != "undefined") ? window.NM_SmartSite_AdID : '';
var class_key = ((typeof(window.NM_SmartSite_ClassKey) != "undefined") && window.NM_SmartSite_ClassKey != null) ? window.NM_SmartSite_ClassKey : '';

var usrHost = '';

var ObjNMEventManager = new NestedMedia.Utility.Class.NMEventManager(clientID,class_key,usrHost);
if(!adID){
  if(clientID) {
    clientID = ObjNMEventManager.cleanString(clientID);
    usrHost = ObjNMEventManager.authenticate(clientID);
    if(usrHost){
      class_key = ObjNMEventManager.cleanString(class_key);
      ObjNMEventManager.addEvent(window, 'load', ObjNMEventManager.handleLoad, false);
      ObjNMEventManager.addEvent(window, 'load', ObjNMEventManager.addListeners, false);
    }
  }
} else {
  class_key = ObjNMEventManager.cleanString(class_key);
  usrHost = location.hostname;
  ObjNMEventManager.addEvent(window, 'load', ObjNMEventManager.handleLoad, false);
  ObjNMEventManager.addEvent(window, 'load', ObjNMEventManager.addListeners, false);
}
