//                       -*- 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.2 2008-05-19 03:56:50 svn Exp $
// Name:    $Name: xos-4-1-1-p0-tag $
//
//

////////////////////////////////////////////////////////////////////////////////
//
//  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 = {};

  ////////////////////////////////////////////////////////////////////////////////
  //
  //  JS/DOM Utilities
  //

  XOS.addEvent = function(o,e,f) {
     if (o.addEventListener){ o.addEventListener(e,f,true); return true; }
     else if (o.attachEvent){ return o.attachEvent("on"+e,f); }
     else { return false; }
  };

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

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

  ////////////////////////////////////////////////////////////////////////////////
  //
  //  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.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;
  };

  XOS.contentInstructionsIncludedP = false;
  XOS.flagContentInstructionsIncluded = function () {
    XOS.contentInstructionsIncludedP = true;
  }

  ////////////////////////////////////////////////////////////////////////////////
  //
  //  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) {
    //FIXME: do we have to worry about sending too much data here or
    //does it get truncated at logged at the allocator end?
    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
          return element.checked ? element.value : null;
        }
        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;
  };

  ////////////////////////////////////////////////////////////////////////////////
  //
  ////  New Methods for the fancy pants editor
  //

  XOS.outcomes = new Array();
  XOS.registerOutcomeThunk = function (name, thunk) {
    XOS.outcomes.push(new Array(name, thunk));
  };

  XOS.segments = new Array();
  XOS.registerSegmentThunk = function (name, thunk) {
    XOS.segments.push(new Array(name, thunk));
  };

  XOS.constructXOSQueryString = function() {
    var queryArgs = new Array();
    var o = XOS.segments;
    for (var i = 0; i < o.length; i = i + 1) {
        var x = o[i];
        var name = x[0];
        var thunk = x[1];
        queryArgs.push(name + '=' + XOS.runSafely( thunk ));
    };
    queryArgs.push("__XOS_FACTS__=YES");
    o = XOS.outcomes;
    for (var i = 0; i < o.length; i = i + 1) {
        var x = o[i];
        var name = x[0];
        var thunk = x[1];
        queryArgs.push(name + '=' + XOS.runSafely( thunk ));
    };
    return queryArgs.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.bodyOnloadFiredP = false;
  XOS.trackOnloadEvent = function() {
    //  FF, IE7 and all the other browser fire the onload in different
    //  orders, at different times with different ways of treating
    //  included scripts.  So we just flag if it has happened here and
    //  then act accordingly later on in our scripts.
    XOS.addEvent( window, 'load', function(){ XOS.bodyOnloadFiredP = true; } );
  };

  XOS.onLoadThunks = [];
  XOS.registerOnloadThunk = function( thunk ) {
    XOS.onLoadThunks.push( thunk );
  };
  XOS.runOnloadThunks = function() {
    for (var idx = 0; idx < XOS.onLoadThunks.length; idx++) {
      XOS.runSafely( XOS.onLoadThunks[idx] );
    }
  };
  XOS.maybeRunOnloadThunks = function() {
    if (XOS.bodyOnloadFiredP) {
      XOS.runOnloadThunks()
    }
    else {
      XOS.addEvent( window, 'load', XOS.runOnloadThunks );
    }
  };
  XOS.runSafely = function( thunk ) {
    try {
      return thunk.apply( null, [] );
    }
    //  squelch 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) {
    XOS.includeScript( storageUrl + "?" + XOS.constructXOSQueryString(), true );
  };

  XOS.captureClick = function (storageUrl, location) {
    // set timer
    XOS.gotoLocation = location;
    setTimeout( function() { document.location.href = location; }, 4000 );
    XOS.storeData(storageUrl);
  };

  //  Global tracking for the onload event.
  XOS.trackOnloadEvent();
};
XOS.tempThunk = function () {
    return 'Application Splash Page';
};;
XOS.registerOutcomeThunk('applicationsplashpage', XOS.tempThunk);
XOS.includeScript('../hidden-execute/' + '2729120235995187760' + '?' + XOS.constructXOSQueryString(), true);