//                       -*- mode: javascript -*-
//
// Author: Memetrics Holding Pty. Ltd. 2005.
//         All Rights Reserved.
//
// License: You may use and extend this library in accordance
//          with the terms of your XOS(TM) license.
//
// Version: $Id: asp-toolkit.js,v 1.1.2.11.2.1 2008-05-01 03:31:23 svn Exp $
// Name:    $Name:  $
//
//

////////////////////////////////////////////////////////////////////////////////
//
//  If you don't have access to your web server config and can't get a
//  P3P header automatically included then a compact version of the
//  policy may be include in each html page by using <meta http-equiv>
//  tags.  For example;
//
// <meta http-equiv="P3P" content='CP="CAO DSP AND SO ON" policyref="/w3c/p3p.xml"' />
//
//  Note DO NOT just copy and paste this into your pages, create a
//  valid P3P policy for your website.



if (! window.XOS) {
  ////////////////////////////////////////////////////////////////////////////////
  //
  //  Global XOS object that

  window.XOS = {};

  ////////////////////////////////////////////////////////////////////////////////
  //
  //  Debugging Helpers
  //
  XOS.log = function () {
    if(window.console) {
      console.log.apply(console,arguments);
    }
  };

  ////////////////////////////////////////////////////////////////////////////////
  //
  //  JS/DOM Utilities
  //
  XOS.addEvent = function(o,e,f) {
     if (o.addEventListener){
       //  The third parameter below indicates whether the event
       //  should be handled during the event capturing phase or the
       //  event bubble phase.  The generally recommended is to use
       //  bubbling in order mimic IE's behaviour which is what we do
       //  below.  NOTE: that for historical reasons we used to do the
       //  opposite but have since discovered that this caused some
       //  subtle inconsistencies between browsers.
       o.addEventListener(e,f,false); return true;
     }
     else if (o.attachEvent){ return o.attachEvent("on"+e,f); }
     else { return false; }
  };

  XOS.cancelEvent = function(event) {
    event = event || window.event;

    // cater for IE
    event.cancelBubble=true;
    // Firefox
    if (event.stopPropagation) { event.stopPropagation(); }
  };
  XOS.preventDefault = function( event ) {
    event = event || window.event;
    if (event.preventDefault) {
      event.preventDefault()
    }
    else {
      event.returnValue = false;
    }
  };
  XOS.stopEvent = function(event) {
    XOS.cancelEvent(event);
    XOS.preventDefault(event);
  };

  XOS.isNullOrUndefined = function( thing ) {
    return (thing === null) || (thing === undefined);
  };

  XOS.hasProperties = function( obj ) {
    for (var key in obj) { return true; }
    return false;
  };

  XOS.hasTagName = function( node, tagName ) {
    if (node && node.tagName) {
      return node.tagName.toLowerCase() == tagName.toLowerCase();
    }
    return false;
  };
  XOS.createElement = function( tagName, attributes ) {
    var element = document.createElement(tagName);
    for (var key in attributes) {
      element.setAttribute(key, attributes[key]);
    }
    return element;
  };

  XOS.intersection = function( l1, l2 ) {
    var test = {};
    for (var idx = 0; idx < l1.length; idx += 1) {
      test[l1[idx]] = 1;
    }

    for (var idx = 0; idx < l2.length; idx += 1) {
      if (test[l2[idx]]) {
        test[l2[idx]] = 2;
      }
    }

    var intersection = [];
    for (var key in test) {
      if (test[key] == 2) {
        intersection.push(key);
      }
    }
    return intersection;
  };

  XOS.permutationP = function(a, b) {
    return (XOS.intersection(a, b).length == a.length) && (a.length == b.length);
  }

  ////////////////////////////////////////////////////////////////////////////////
  //
  //  Functional Helpers
  //
  XOS.identity = function( thing ) {
    return thing;
  };

  XOS.removeIf = function( predicate, list ) {
    var results = [];
    for (var idx = 0; idx < list.length; idx++) {
      if (!predicate( list[idx] )) {
        results.push( list[idx] );
      }
    }
    return results;
  };

  XOS.removeIfNot = function( predicate, list ) {
    var results = [];
    for (var idx = 0; idx < list.length; idx++) {
      if (predicate( list[idx] )) {
        results.push( list[idx] );
      }
    }
    return results;
  };

  //  An extremely simple map, treats each entry in the list as a
  //  arguments to the function.
  //
  //  Example Usage: map( function( p ){ return p + 2; }, [1, 2, 3] );
  XOS.mapApply = function( fn, list ) {
    var result = [];
    var args   = null;
    for (var idx = 0; idx < list.length; idx++) {
      args = list[idx];

      //  If the args are already a list, assume that the caller knows
      //  what they are doing and wants these passed as arguments to the
      //  function.  However as a convenience if we only have a single
      //  argument for each call just wrap it in a list to stop JS from
      //  complaining.  We do this instead of just calling fn( args ) as
      //  we want to explicitly make this == null to avoid any crazy JS
      //  this wrangling and hence unexpected behaviour.
      if ((typeof(args)        == 'string') ||
          (typeof(args.length) != 'number')) {
        args = [args];
      }
      result.push( fn.apply( null, args ) );
    }
    return result;
  };

  ////////////////////////////////////////////////////////////////////////////////
  //
  //  Misc Helpers
  //
  XOS.items = function (obj) {
    var result = [];
    var e;
    for (var prop in obj) {
      var v;
      try {
        v = obj[prop];
      } catch (e) {
        continue;
      }
      result.push([prop, v]);
    }
    return result;
  };

  //  Joins the arguments together inserting the prefix between each.
  //  null/undefined arguments are ignored
  XOS.join = function() {
    if (arguments.length < 2) { return arguments[1] || ""; }

    var prefix    = arguments[0];
    var delimiter = "";
    var result    = "";
    for (var i = 1; i < arguments.length; i++) {
      if (! XOS.isNullOrUndefined(arguments[i])) {
        result    = result + delimiter + arguments[i];
        delimiter = prefix;
      }
    }
    return result;
  };

  //  The JS execution model means that each script is executed before
  //  the next one (if any) is loaded, this means that at the time the
  //  following bit of JS runs this script (ie, asp-toolkit.js) will be
  //  the last <script> element in the header.
  //
  //  We use this to remember the location of this script so we can
  //  dynamically add other scripts that are in the same location.
  XOS.SCRIPT_PATH = null;
  XOS.setupGlobalScriptPath = function() {
    var scripts = document.getElementsByTagName( "script" );
    if (scripts.length === 0) {
      throw new Error( "Failed to find the current script element." );
    }
    else {
      XOS.SCRIPT_PATH = scripts[scripts.length - 1].src;
      var pos         = XOS.SCRIPT_PATH.lastIndexOf( "/" );
      XOS.SCRIPT_PATH = (pos == -1) ? "" : XOS.SCRIPT_PATH.substring(0, pos + 1);
    }
  };
  XOS.setupGlobalScriptPath();

  XOS.includeScript = function( name, relative /*optional: defaults to false*/ ) {
    //  Can optionally load javascript relative to the location of this script.
    var url = relative ? XOS.SCRIPT_PATH + name : name;

    var result = document.createElement( "script" );
    result.setAttribute( "src", url );

    document.getElementsByTagName( "HEAD" )[0].appendChild( result );
    return result;
  };


  ////////////////////////////////////////////////////////////////////////////////
  //
  //  User Utility Methods
  //

  //  Returns the value for the given key from the query string.  If
  //  no value is found or if the value found evaluates to false then
  //  defaultVal is returned.
  XOS.getQueryStringValue = function( val, defaultVal ) {
    if (!XOS.QueryArray) {
      XOS.QueryArray = [];
      var pos = null;
      var pairs = window.location.search.substring(1).split('&');
      for (var i = 0; i < pairs.length; i++) {
        pos = pairs[i].indexOf('=');
        if (pos > 0) {
          XOS.QueryArray[unescape(pairs[i].substring(0,pos))] = unescape(pairs[i].substring(pos+1));
        }
      }
    }
    return (XOS.QueryArray[val] || defaultVal);
  };

  XOS.getDomNodeContent = function(domId, defaultValue) {
    var element = XOS.getElement( domId );
    if (element) {
      var tag = element.tagName.toUpperCase();
      if (tag == 'TEXTAREA') {
        return element.value;
      }
      else if (tag == 'INPUT') {
        var type = element.type.toUpperCase();
        if ((type == 'RADIO') || (type == 'CHECKBOX')) {
          // return the value if it is checked, empty string otherwise
          return element.checked ? element.value : "";
        }
        return element.value;
      }
      return element.innerHTML;
    }
    return defaultValue;
  };

  XOS.getQueryString = function() {
     var result = document.location.search;
     return result.charAt(0) == '?' ? result.substring(1) : result;
  };

  XOS.getElement = function( elementOrId ) {
    return (typeof(elementOrId) == "string") ? document.getElementById( elementOrId ) : elementOrId;
  };

  ////////////////////////////////////////////////////////////////////////////////
  //
  ////  Campaign Editor Methods
  //
  XOS.appendQueryStringParts = function(queryParts, queryComponents) {
    //  Takes a list of pairs containing [name, thunk] and appends
    //  strings mapping name to the result of calling thunk to
    //  queryComponents.
    if (queryParts) {
      for (var i = 0; i < queryParts.length; i = i + 1) {
        var name  = queryParts[i][0];
        var thunk = queryParts[i][1];
        queryComponents.push(encodeURIComponent(name) + '=' + encodeURIComponent( XOS.runSafely( thunk )));
      };
    }
  };

  XOS.constructXOSQueryString = function(segmentParts, outcomeParts) {
    var queryComponents = [];
    XOS.appendQueryStringParts(segmentParts, queryComponents);
    queryComponents.push("__XOS_FACTS__=YES");
    XOS.appendQueryStringParts(outcomeParts, queryComponents);
    return queryComponents.join( "&" );
  };

  XOS.getCookie = function( name ) {
    var start = document.cookie.indexOf( name + "=" );
    var len = start + name.length + 1;
    if ((!start) && (name != document.cookie.substring( 0, name.length ))) {
      return null;
    }

    if (start == -1) {
      return null;
    }

    var end = document.cookie.indexOf( ';', len );
    if (end == -1) {
      end = document.cookie.length;
    }

    return unescape( document.cookie.substring( len, end ) );
  };

  XOS.getCookieValue = function( name, defaultVal ) {
    return XOS.getCookie( name ) || defaultVal;
  };

  // The next two sets of functions have to collaborate to
  // orchestrate proper execution of the cleanup or content thunks.
  // The rules is simple:
  //  First, if you're told to do something, you register it for later
  //  execution, unless you've already executed, in which case you
  //  do it right away.   Second, if your partner has already run,
  //  you do nothing. (making `cleanup' and `content' mutually exclusive.)
  XOS.onloadHasRun  = false;
  XOS.cleanupHasRun = false;
  XOS.contentHasRun = false;

  XOS.cleanupThunks = [];
  XOS.registerCleanupThunk = function( thunk ) {
    if (XOS.contentHasRun) { return false; }

    if (XOS.cleanupHasRun) {
      XOS.runSafely( thunk );
    }
    else {
      XOS.cleanupThunks.push( thunk );
    }
  };

  XOS.runCleanupThunks = function() {
    if (XOS.contentHasRun) { return false; }
    XOS.doDefaults();
  };
  //  Equivalent of the onload handler for content instructions
  XOS.timeoutID = setTimeout( XOS.runCleanupThunks, 10000);

  XOS.doDefaults = function() {
    if (XOS.cleanupHasRun) { return false; }
    XOS.cleanupHasRun = true;
    for (var idx = 0; idx < XOS.cleanupThunks.length; idx++) {
      XOS.runSafely( XOS.cleanupThunks[idx] );
    }
  };

  XOS.contentInstructionThunks = [];
  XOS.registerContentThunk = function( thunk ) {
    if (XOS.cleanupHasRun) { return false; }

    if (XOS.onloadHasRun) {
      XOS.contentHasRun = true;
      XOS.runSafely( thunk );
    }
    else {
      XOS.contentInstructionThunks.push( thunk );
    }
  };

  XOS.runContentInstructionThunks = function() {
    XOS.onloadHasRun = true;

    if (XOS.cleanupHasRun) { return false; }

    for (var idx = 0; idx < XOS.contentInstructionThunks.length; idx++) {
      XOS.contentHasRun = true;
      XOS.runSafely( XOS.contentInstructionThunks[idx] );
    }
  };
  //  Hook the onload to try and ensure our thunks are all run.
  XOS.addEvent( window, 'load', XOS.runContentInstructionThunks );

  XOS.setupContentInstructionThunks = function( preThunk, contentThunks, postThunk ) {

  };

  XOS.runSafely = function( thunk ) {
    try {
      return thunk.apply( null, [] );
    }
    //  ignore any errors
    catch (e) { };
  };
  XOS.validXPathExpressionP = function( xpath ) {
    try {
      document.createExpression( xpath, null );
      return true;
    }
    /* squelch */
    catch (e) { }
    return false;
  };
  XOS.getElementByXPath = function( xpath ) {
    if (XOS.validXPathExpressionP(xpath)) {
      var result = document.evaluate(xpath, document, null, 7, null);
      return result ? result.snapshotItem(0) : null;
    }
    return null;
  };
  XOS.studlify = function( name ) {
    var components = name.toLowerCase().split('-');
    var result = components[0];
    for (var i = 1; i < components.length; i++) {
      result += components[i].charAt(0).toUpperCase() + components[i].substring(1);
    }
    return result;
  };
  XOS.setStyle = function( elem, style ) {
    // opacity not treated handled gracefully at this point.
    // opacity for IE requires alpha:filter, etc.
    for (var name in style) {
      elem.style[XOS.studlify(name)] = style[name] || "";
    }
  };
  XOS.setRawCss = function( elem, css ) {
    if (css) { elem.setAttribute( 'style', css ); }
  };
  XOS.addStylesheet = function( contents, elementId /*optional*/ ) {
    var style = document.createElement("style");
    style.setAttribute("type", "text/css");
    if (elementId) {
      style.setAttribute("id", elementId);
    }

    // IE
    if(style.styleSheet){
      style.styleSheet.cssText = contents;
    }
    //..w3c
    else {
      style.appendChild(document.createTextNode(contents));
    }

    //  Finally add it into the head of the document
    var head = document.getElementsByTagName("head").item(0);
    head.appendChild( style );
  };
  XOS.stylesheetIncludedP = function( elementId ){
    return document.getElementById( elementId );
  };

  XOS.maybeGotoStoredLocation = function () {
    if (XOS.gotoLocation) {
      document.location.href = XOS.gotoLocation;
    }
  };

  XOS.storeData = function (storageUrl, segmentPartsMaker, outcomePartsMaker) {
    var segmentParts = segmentPartsMaker ? segmentPartsMaker() : null;
    var outcomeParts = outcomePartsMaker ? outcomePartsMaker() : null;
    XOS.includeScript(storageUrl + "?" + XOS.constructXOSQueryString(segmentParts, outcomeParts), true);
  };

  XOS.findClickCaptureHref = function (elem) {
    //  Find the first available href attribute either on the elem or
    //  on a parent.  NOTE: this function does not care what type of
    //  elem it is given so a DIV with an href will work just as well
    //  as an anchor with an href.
    var attr = null;
    while(elem) {
      //  We want a rigorous test for the existence of the attribute
      //  node called 'href', if we use elem.href then in IE6,7 for
      //  IMG elements we get the value of the SRC attribute returned.
      attr = elem.attributes.getNamedItem('href');
      if (attr) { return attr.value; }
      elem = elem.parentNode;
    }
    return null;
  };

  XOS.captureClick = function (storageUrl, location, segmentPartsMaker, outcomePartsMaker) {
    //  Goto the specified location and back to the current location
    //  in the case where we dont have a location, we should _always_
    //  have a location so this just caters for very peculiar corner
    //  cases and ensures we don't let a user see a 404.
    XOS.gotoLocation = location;
    setTimeout( function() { document.location.href = location; }, 4000 );
    XOS.storeData(storageUrl, segmentPartsMaker, outcomePartsMaker);
  };

  XOS.reorderElements = function (originalOrder, newOrder) {
    if (!XOS.permutationP(originalOrder, newOrder)) {
      XOS.log(originalOrder, ' is not a permuation of ', newOrder, ', cannot reorder DOM elements.');
      return null;
    }
    var originalOrder = XOS.mapApply(XOS.getElement, originalOrder);
    var newOrder      = XOS.mapApply(XOS.getElement, newOrder);

    for (var idx = 0; idx < originalOrder.length; idx = idx + 1) {
      var originalElement = originalOrder[idx];
      var newElement      = newOrder[idx];
      var dummy = XOS.createElement('div', { id : newElement.id });
      originalElement.parentNode.replaceChild(dummy, originalElement);
    }

    for (var idx = 0; idx < newOrder.length; idx = idx + 1) {
      var newElement = newOrder[idx];
      var dummy = XOS.getElement(newElement.id);
      dummy.parentNode.replaceChild(newElement, dummy);
    }
  };
};
XOS.addStylesheet('\n');
XOS.registerCleanupThunk(function () {
    XOS.addStylesheet('\n', 'XOS-SHOW-ELEMENTS');
});
var segmentThunks = function () {
    var thunk = null;
    var thunks = [];
    thunk = function () {
    return (window.g_eep) ? (window.g_eep) : XOS.getQueryStringValue('eep', 'undefined');
};;
    thunks.push(['referringEEP', thunk]);
    thunk = function () {
    var ct = XOS.getQueryStringValue('ct', 'undefined');
    if (ct=='24') return 'BGR';
    if (ct=='75') return 'SC';
    if (ct=='70') return 'SW';
    if (ct=='22') return 'DG';
    if (location.pathname.indexOf("the-gold-card") > -1) return 'BGR';
};
    thunks.push(['CARD', thunk]);
    return thunks;
};
XOS.storeData('../hidden-execute/' + '7164197912065103065', segmentThunks, null);