function getParam(name)
{
  var regexS = "[\\?&]"+name+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var targetURL = window.location.href;
  var results = regex.exec( targetURL );
  if( results == null )
    return "";
  else
    return results[1];
}
function getDriver(currentHref)
{
  var key = "d";
  if (top.location.href.indexOf('?') > -1)
  {
    if (currentHref.indexOf('?') > -1)
    {
      var newQuery = "";

      var targetJSP = currentHref.substr(0, currentHref.indexOf('?'));
      var query = currentHref.substr(currentHref.indexOf('?'));
      var keyValuePairs = query.split("&");

      var queryParams = currentHref.substr(currentHref.indexOf('?') + 1);
      var ParamPairs = queryParams.split("&");

      var value = getParam(key);

      for (var k = 0; k < keyValuePairs.length; k++)
      {
        if (ParamPairs[k].split("=")[0] == key)
        {
          var thePair = keyValuePairs[k].split("=");
          keyValuePairs[k] = thePair[0] + "=" + value;
        }

        if (k != 0)
        {
          newQuery += "&";
        }
        newQuery += keyValuePairs[k];
      }
      return targetJSP + newQuery;
    }
    else
    {
      var finalHREF = currentHref + top.location.href.substr(window.location.href.indexOf('?'))
      return finalHREF;
    }
  }
  else
  {
    return currentHref;
  }
}


function getURLParam(strParamName){
  var strReturn = "";
  var strHref = window.location.href;
  if ( strHref.indexOf("&") > -1 ){
    var strQueryString = strHref.substr(strHref.indexOf("&")).toLowerCase();
    var aQueryString = strQueryString.split("&");
    for ( var iParam = 0; iParam < aQueryString.length; iParam++ ){
      if (aQueryString[iParam].indexOf(strParamName + "=") > -1 ){
        var aParam = aQueryString[iParam].split("=");
        strReturn = aParam[1];
        break;
      }
    }
  }
  return strReturn;
}

function isValidPhoneNumber(num, requiredDigits) {
    var digits = 0;
    if (num == null) return false;
    for( i=0; i<num.length; i++ ){
        var c = num.charCodeAt(i);
        //convert the i-th character to ascii code value
        if( (c>=48) && (c<=57) ) digits++;
    }
    return (digits >= requiredDigits);
}

/********
 * Verify that an email addres is valid
 * Written by Paolo Wales (paolo@taize.fr)
********/

function isValidEmail(emailad) {

   var exclude=/[^@\-\.\w\']|^[_@\.\-]|[\._\-]{2}|[@\.]{2}|(@)[^@]*\1/;
   var check=/@[\w\-]+\./;
   var checkend=/\.[a-zA-Z]{2,4}$/;
   if(((emailad.search(exclude) != -1) ||
       (emailad.search(check)) == -1) ||
       (emailad.search(checkend) == -1)){
      return false;
   } else {
      return true;
   }
}

/********
 * Ensures valid emails are present and that the sender email doesn't contain
 * an 'salesforce.com' in the sender's domain.
 *
 * use: for "email a friend" security
 * created by: Scott Yancey
********/

function isValidEmails() {

   var recipientEmail = document.forms[0].recipientEmail.value;
   var senderEmail = document.forms[0].senderEmail.value;
   var error = false;

   var errorMessage = "The following errors are present:\n\n";

   if (recipientEmail.indexOf(',') < 0) {
       if (!isValidEmail(recipientEmail)){
         error = true;
      errorMessage += "The recipient's Email address is not valid\n"
       }
   } else {

      var addresses = new Array();
   addresses = recipientEmail.split(',');
   var currentAddress;
   var i;
   for (var i=0; i < addresses.length; i++) {

    if (!isValidEmail(trim(addresses[i]))){
         error = true;
         }

   }
   if (i > 10) {
      error = true;
      errorMessage += "Only 10 addresses are allowed\n"
   }
   if (error) {
     errorMessage += "A recipient's Email address is not valid\n"
   }

   }

   if (!isValidEmail(senderEmail)) {
     error = true;
  errorMessage += "The sender's Email address is not valid"
   }
   if (senderEmail.indexOf("salesforce.com") >= 0) {
     error = true;
  errorMessage += "The sender's Email address can not contain 'salesforce.com'."
   }

   if (error) {
      alert(errorMessage);
      return false;
   } else {
      return true;
   }
}

//added by K Guckian moved over from existing site js this is for the interactive screenshot

function launchDemo(url){
  var winwidth=screen.width;
  var winheight=screen.height;
  var scroll="";

  if(winwidth>1000){
    winwidth=1020;
    winheight=700;
    scroll="no";
  }else if(winwidth<1000){
    winwidth=790;
    winheight=530;
    scroll="yes";
  }
  url=url+"&scroll="+scroll;
  newWindow=window.open(url,"Demo","toolbar=no,scrollbars=no,resizable=no,width="+winwidth+",height="+winheight+",left=0,top=0");
}

function referFriend(url){
        var referurl=document.location.href;
        url=url+"?referurl=" + referurl+"&title="+document.title;
  newWindow=window.open(url,"","toolbar=no,scrollbars=no,resizable=no,width=350,height=500,left=0,top=0");
}

/**
*
*  URL encode / decode
*  http://www.webtoolkit.info/
*
**/

var Url = {

    // public method for url encoding
    encode : function (string) {
        return escape(this._utf8_encode(string));
    },

    // public method for url decoding
    decode : function (string) {
        return this._utf8_decode(unescape(string));
    },

    // private method for UTF-8 encoding
    _utf8_encode : function (string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";

        for (var n = 0; n < string.length; n++) {

            var c = string.charCodeAt(n);

            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }

        }

        return utftext;
    },

    // private method for UTF-8 decoding
    _utf8_decode : function (utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;

        while ( i < utftext.length ) {

            c = utftext.charCodeAt(i);

            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }

        }

        return string;
    }

}

/**
*
*  Base64 encode / decode
*  http://www.webtoolkit.info/
*
**/

var Base64 = {

    // private property
    _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

    // public method for encoding
    encode : function (input) {
        var output = "";
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        var i = 0;

        input = Base64._utf8_encode(input);

        while (i < input.length) {

            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);

            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;

            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }

            output = output +
            this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
            this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

        }

        return output;
    },

    // public method for decoding
    decode : function (input) {
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;

        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

        while (i < input.length) {

            enc1 = this._keyStr.indexOf(input.charAt(i++));
            enc2 = this._keyStr.indexOf(input.charAt(i++));
            enc3 = this._keyStr.indexOf(input.charAt(i++));
            enc4 = this._keyStr.indexOf(input.charAt(i++));

            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;

            output = output + String.fromCharCode(chr1);

            if (enc3 != 64) {
                output = output + String.fromCharCode(chr2);
            }
            if (enc4 != 64) {
                output = output + String.fromCharCode(chr3);
            }

        }

        output = Base64._utf8_decode(output);

        return output;

    },

    // private method for UTF-8 encoding
    _utf8_encode : function (string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";

        for (var n = 0; n < string.length; n++) {

            var c = string.charCodeAt(n);

            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }

        }

        return utftext;
    },

    // private method for UTF-8 decoding
    _utf8_decode : function (utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;

        while ( i < utftext.length ) {

            c = utftext.charCodeAt(i);

            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }

        }

        return string;
    }

}


function encode64(input) {

  return Base64.encode(input);

}

function decode64(input) {

  return Base64.decode(input);

}

function getArgs(arg_name, str) {
 var value = "", tmpstr = "";
 if (!str) str = location.search.substring(1);
 if (!str) return value;
 else {
  var tmparray = str.split("&");
  for (i=0; i<tmparray.length; i++) {
   tmpstr = tmparray[i];
   if (tmpstr.indexOf(arg_name + "=") != -1) {
    var tmp2array = tmparray[i].split("=");
    value = tmp2array[1];
   }
  }
 }
 return value;
}


var Server = {

  network : 'salesforce.com',
  stagingDomains : ['internal.salesforce.com','soma.salesforce.com','localhost'],

  isProduction : function() {
    for (i in this.stagingDomains) {
      if (self.location.href.indexOf(this.stagingDomains[i]) > 0) {
        this.network = this.stagingDomains[i];
        break;
      }
    }
     return (this.network=='salesforce.com');
  },

  isStage : function() {
     return !this.isProduction();
  }
}


/**
*
*  Javascript cookies
*  http://www.webtoolkit.info/
*
**/

function CookieHandler() {

    this.setCookie = function (name, value, seconds) {

        var expires = "";
        var expiresNow = "";
        var date = new Date();
        date.setTime(date.getTime() + (-1*1000));
        expiresNow = "; expires=" + date.toGMTString();

        if (typeof(seconds) != 'undefined') {
            date.setTime(date.getTime() + (seconds*1000));
            expires = "; expires=" + date.toGMTString();
        }

        // fix production scoping issues
        // keep writing the old cookie, but make it expire
        document.cookie = name + "=" + value + expiresNow + "; path=/";
        // now just set the right one
        document.cookie = name + "=" + value + expires + "; path=/; domain=.salesforce.com";
    }

    this.getCookie = function (name) {

        name = name + "=";
        var carray = document.cookie.split(';');

        for(var i=0;i < carray.length;i++) {
            var c = carray[i];
            while (c.charAt(0)==' ') c = c.substring(1,c.length);
            if (c.indexOf(name) == 0) return c.substring(name.length,c.length);
        }

        return null;
    }

    this.deleteCookie = function (name) {
        this.setCookie(name, "", -1);
    }

}



/********
 * Opens a new window
********/

var curPopupWindow = null;

function openWindow(url, winName, width, height, center, winType) {

   var xposition = 50; // Postions the window vertically in px
   var yposition = 50; // Postions the window horizontally in px
   var location, menubar, resizable, scrollbars, status, titlebar;

   if ((parseInt(navigator.appVersion) >= 4 ) && (center)){
       xposition = (screen.width - 800) / 2;
       yposition = (screen.height - 600) / 2;
   }

   if (winType == "1") {           // winType 1 is for regular popup windows
      location=1;
      menubar=1;
      resizable=1;
      scrollbars=1;
      status=1;
      titlebar=1;
   } else if (winType == "2") {   // winType 2 is for Quick Tour like popups
      location=0;
      menubar=0;
      resizable=0;
      scrollbars=0;
      status=0;
      titlebar=1;
   } else if (winType == "3") {   // winType 3 is for footer like popups
      location=0;
      menubar=0;
      resizable=1;
      scrollbars=1;
      status=0;
      titlebar=1;
   } else if (winType == "4") { // winType 4 sforce footer - no resizing
      location=0;
      menubar=0;
      resizable=0;
      scrollbars=1;
      status=0;
      titlebar=0;
   } else if (winType == "5") {
      location=0;
      menubar=1;
      resizable=0;
      scrollbars=1;
      status=0;
      titlebar=0;
   }else {                       // if no arg is passed for winType
      location=1;
      menubar=1;
      resizable=1;
      scrollbars=1;
      status=1;
      titlebar=1;
   }

   // Features to specify for a new window
   args = "width=" + width + ","
   + "height=" + height + ","
   + "location=" + location + ","
   + "menubar=" + menubar + ","
   + "resizable=" + resizable + ","
   + "scrollbars=" + scrollbars + ","
   + "status=" + status + ","
   + "titlebar=" + titlebar + ","
   + "toolbar=0,"
   + "hotkeys=0,"
   + "screenx=" + xposition + ","  //NN Only
   + "screeny=" + yposition + ","  //NN Only
   + "left=" + xposition + ","     //IE Only
   + "top=" + yposition;           //IE Only

  // Performs the opening of the window (and closing of a window already opened for that page).
  if (curPopupWindow != null) {
    curPopupWindow.close();
  }
  curPopupWindow = window.open(url, winName, args, false);
  curPopupWindow.focus();
}

function readCookie(name) {
  var c = new CookieHandler();
  return c.getCookie(name);
}

function toggleElementDisplay( elementId ) {
  var element = document.getElementById( elementId );
  var currentState = element.style.display;

  if (!currentState || currentState == 'none') {
    element.style.display = "block";
  } else {
    element.style.display = "none";
  }
}


/*
    http://www.JSON.org/json2.js
    2008-11-19

    Public Domain.

    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.

    See http://www.JSON.org/js.html
*/

if (!this.JSON) {
    JSON = {};
}
(function () {

    function f(n) {
        return n < 10 ? '0' + n : n;
    }

    if (typeof Date.prototype.toJSON !== 'function') {

        Date.prototype.toJSON = function (key) {

            return this.getUTCFullYear()   + '-' +
                 f(this.getUTCMonth() + 1) + '-' +
                 f(this.getUTCDate())      + 'T' +
                 f(this.getUTCHours())     + ':' +
                 f(this.getUTCMinutes())   + ':' +
                 f(this.getUTCSeconds())   + 'Z';
        };

        String.prototype.toJSON =
        Number.prototype.toJSON =
        Boolean.prototype.toJSON = function (key) {
            return this.valueOf();
        };
    }

    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        gap,
        indent,
        meta = {    // table of character substitutions
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        },
        rep;


    function quote(string) {

        escapable.lastIndex = 0;
        return escapable.test(string) ?
            '"' + string.replace(escapable, function (a) {
                var c = meta[a];
                return typeof c === 'string' ? c :
                    '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
            }) + '"' :
            '"' + string + '"';
    }


    function str(key, holder) {

        var i,          // The loop counter.
            k,          // The member key.
            v,          // The member value.
            length,
            mind = gap,
            partial,
            value = holder[key];

        if (value && typeof value === 'object' &&
                typeof value.toJSON === 'function') {
            value = value.toJSON(key);
        }

        if (typeof rep === 'function') {
            value = rep.call(holder, key, value);
        }

        switch (typeof value) {
        case 'string':
            return quote(value);

        case 'number':

            return isFinite(value) ? String(value) : 'null';

        case 'boolean':
        case 'null':

            return String(value);

        case 'object':

            if (!value) {
                return 'null';
            }

            gap += indent;
            partial = [];

            if (Object.prototype.toString.apply(value) === '[object Array]') {

                length = value.length;
                for (i = 0; i < length; i += 1) {
                    partial[i] = str(i, value) || 'null';
                }

                v = partial.length === 0 ? '[]' :
                    gap ? '[\n' + gap +
                            partial.join(',\n' + gap) + '\n' +
                                mind + ']' :
                          '[' + partial.join(',') + ']';
                gap = mind;
                return v;
            }

            if (rep && typeof rep === 'object') {
                length = rep.length;
                for (i = 0; i < length; i += 1) {
                    k = rep[i];
                    if (typeof k === 'string') {
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            } else {

                for (k in value) {
                    if (Object.hasOwnProperty.call(value, k)) {
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            }

            v = partial.length === 0 ? '{}' :
                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
                        mind + '}' : '{' + partial.join(',') + '}';
            gap = mind;
            return v;
        }
    }

    if (typeof JSON.stringify !== 'function') {
        JSON.stringify = function (value, replacer, space) {

            var i;
            gap = '';
            indent = '';

            if (typeof space === 'number') {
                for (i = 0; i < space; i += 1) {
                    indent += ' ';
                }

            } else if (typeof space === 'string') {
                indent = space;
            }

            rep = replacer;
            if (replacer && typeof replacer !== 'function' &&
                    (typeof replacer !== 'object' ||
                     typeof replacer.length !== 'number')) {
                throw new Error('JSON.stringify');
            }

            return str('', {'': value});
        };
    }

    if (typeof JSON.parse !== 'function') {
        JSON.parse = function (text, reviver) {

            var j;

            function walk(holder, key) {

                var k, v, value = holder[key];
                if (value && typeof value === 'object') {
                    for (k in value) {
                        if (Object.hasOwnProperty.call(value, k)) {
                            v = walk(value, k);
                            if (v !== undefined) {
                                value[k] = v;
                            } else {
                                delete value[k];
                            }
                        }
                    }
                }
                return reviver.call(holder, key, value);
            }

            cx.lastIndex = 0;
            if (cx.test(text)) {
                text = text.replace(cx, function (a) {
                    return '\\u' +
                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
                });
            }

            if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

                j = eval('(' + text + ')');

                return typeof reviver === 'function' ?
                    walk({'': j}, '') : j;
            }

            throw new SyntaxError('JSON.parse');
        };
    }
})();

// convert case-sensitve to insensitive ids
function convert15To18(id) {
  if (id == null || id.length == 18) {
    return id;
  } else if (id.length != 15) {
    return null;
  } else {
    var suffix = "";
    for (var i = 0; i < 3; i++) {
      var flags = 0;
      for (var j = 0; j < 5; j++) {
        var c = id.charAt(i * 5 + j);
        if (c >= 'A' && c <= 'Z') {
          flags += 1 << j;
        }
      }
      if (flags <= 25) {
        suffix += "ABCDEFGHIJKLMNOPQRSTUVWXYZ".charAt(flags);
      } else {
        suffix += "012345".charAt(flags-26);
      }
    }
    return id + suffix;
  }
}



/**
 * Visitor Profile JS Wrapper
 * @author jburbridge
 * @since w156.3
 * ***********************************************/

function VisitorProfile() {

  this.version = 'w158.1';

  // get all the profile and activity data from cookies
  this.cookiejar = new CookieHandler();
  this.profileData = this.getJSONCookie('appxud');
  this.activityData = this.getJSONCookie('webact');

  // get the oinfo cookie values
  var orgStatus = this.OrgInfo.getStatus();
  var orgType = this.OrgInfo.getType();

  // prepare timestamp
  var now = new Date();
  this.timestamp = now.getTime();

  // check if the activity cookie for known free trial
  // or set a new one if the oinfo cookie says they do
  if (!this.isTrialUser()) {
    if (orgStatus=='TRIAL') {
      this.activityData['trial'] = this.timestamp;
    }
  }

  // now check whether they have a valid customer cookie
  if (!this.isCustomer()) {
    if ((orgStatus == 'ACTIVE' || orgStatus == 'DEMO' || orgStatus == 'FREE')
        && (orgType != 'ME' && orgType != 'DE')) {
      this.activityData['customer'] = this.timestamp;
    }
  }

  // are they a developer?
  if (!this.isDeveloper()) {
    if (orgType == 'DE') {
      this.activityData['developer'] = this.timestamp;
    }
  }

  // update session details
  var sessionLength = 30*60; // 30 mins
  if (this.sessionTimer() > sessionLength) {
    this.activityData['l_visit'] = this.getSession();
    if (this.lastVisit() >= this.firstVisit()) {
      this.activityData['counter']++;
    }
  }
  this.idle = this.sessionTimer();
  this.activityData['session'] = this.timestamp;

  // set new visitor details
  if (this.isNewVisitor()) {
    this.activityData['counter'] = 0;
    if (this.firstVisit() == 0) {
      this.activityData['f_visit'] = this.timestamp;
      this.activityData['version'] = this.version;
    }
  }


  /* TODO:
   * create an entry to pick-up demo center vistors
   * and form completes from contact me pages
   */

   this.saveActivityData();

}

/**
 * Cookie / JSON Utils
 **************************************************/

VisitorProfile.prototype.getCookieData = function(cookieName) {
//	return this.cookiejar.getCookie(cookieName); // TODO: fix this!
  return readCookie(cookieName);
}

VisitorProfile.prototype.getBase64Cookie = function(cookieName) {
  return Base64.decode(unescape(this.getCookieData(cookieName)));
}

VisitorProfile.prototype.getJSONCookie = function(cookieName) {
  var objectData = new Object();
  try {
    var cookieData = this.getCookieData(cookieName);
    if (cookieData != null) {
      objectData = JSON.parse(unescape(cookieData));
    }
  } catch (err) {
    if (Server.isStage()) {
      throw err;
    }
  }
  return objectData;
}

/**
 * Methods for handling activities
 **************************************************/

VisitorProfile.prototype.saveActivityData = function() {
  var cookieValue = escape(JSON.stringify(this.activityData));
  this.cookiejar.setCookie('webact',cookieValue,60*60*24*365); // exp 1 year
  return cookieValue;
}

VisitorProfile.prototype.getActivity = function(propertyName) {
  // always return an empty string instead of a null
  // so we can safely print back to form values easily
  if (this.activityData != null) {
     return (this.activityData[propertyName] != null ? this.activityData[propertyName] : '');
   } else {
     return '';
   }
}

// TODO: work in progress
VisitorProfile.prototype.getProfileLevel = function() {
   var profileNum=0;
  ((this.isCustomer) && (!this.isDeveloper()) ) ? profileNum = 1 : 0; //Customer
  ((this.isDeveloper()) && (!this.isCustomer())) ? profileNum = 2 : 0; //Developer
  ((!this.isCustomer()) && (!this.isDeveloper()) && (this.isNewVisitor()) && (!this.isTrialUser()) && (!this.lastDemoCenter())) ? profileNum =3 : 0; //Non-Customer,  First Time visitor, no-trial, no demo
  ((!this.isCustomer()) && (!this.isDeveloper()) && (!this.isNewVisitor()) && (!this.isTrialUser()) && (!this.lastDemoCenter())) ? profileNum =4 : 0; //Non-Customer, Repeat Visitor, no-trial, no demo
  ((!this.isCustomer()) && (!this.isDeveloper()) && (!this.isNewVisitor()) && (!this.isTrialUser()) && (this.lastDemoCenter())) ? profileNum =5 : 0; //Non-Customer, Repeat Visitor, no Trial, Demo
  ((!this.isCustomer()) && (!this.isDeveloper()) && (!this.isNewVisitor()) && (this.isTrialUser()) && (!this.lastDemoCenter())) ? profileNum =6 : 0; //Non-Customer, Repeat Visitor, Trial, no Demo
  ((!this.isCustomer()) && (!this.isDeveloper()) && (!this.isNewVisitor()) && (this.isTrialUser()) && (!this.lastDemoCenter())) ? profileNum =7 : 0; //Non-Customer, Repeat Visitor, Trial, no Demo
  ((!this.isCustomer()) && (!this.isDeveloper()) && (!this.isNewVisitor()) && (this.isTrialUser()) && (this.lastDemoCenter())) ? profileNum =8 : 0; //Non-Customer, Repeat Visitor, Trial, Demo
  return profileNum;
}

// precedence is important here!
VisitorProfile.prototype.getType = function() {
  if (this.isEmployee()) {
    return 'employee';
  } else if (this.isCustomer()) {
    return 'customer';
  } else if (this.isDeveloper()) {
    return 'developer';
  } else if (this.getUserEmail()) {
    return 'known prospect';
  } else {
    return 'anonymous';
  }
}

VisitorProfile.prototype.isEmployee = function() {
  var login = this.getCookieData('login');
  var domains = ['@salesforce.com','@supportforce.com','@dreamforce.com'];
  if (login) {
    for (d in domains) {
      if (login.indexOf(domains[d]) > 0) {
        return true;
        break;
      }
    }
  }
  return false;
}

VisitorProfile.prototype.isCustomer = function() {
   return (this.getActivity('customer') > 0);
}

VisitorProfile.prototype.isDeveloper = function() {
   return (this.getActivity('developer') > 0);
}

VisitorProfile.prototype.isTrialUser = function() {
   return (this.getActivity('trial') > 0);
}

VisitorProfile.prototype.getVisitNumber = function() {
   return (this.getActivity('counter') > 0 ? this.getActivity('counter') : 0);
}

VisitorProfile.prototype.isNewVisitor = function() {
  return (this.getVisitNumber()==0);
}

VisitorProfile.prototype.lastFreeTrial = function() {
   return (this.getActivity('trial') > 0 ? this.getActivity('trial') : 0);
}

VisitorProfile.prototype.lastContactMe = function() {
   return (this.getActivity('contact') > 0 ? this.getActivity('contact') : 0);
}

VisitorProfile.prototype.lastDemoCenter = function() {
   return (this.getActivity('demo') > 0 ? this.getActivity('demo') : 0);
}

VisitorProfile.prototype.lastVisit = function() {
   return (this.getActivity('l_visit') > 0 ? this.getActivity('l_visit') : 0);
}

VisitorProfile.prototype.firstVisit = function() {
   return (this.getActivity('f_visit') > 0 ? this.getActivity('f_visit') : 0);
}

VisitorProfile.prototype.getSession = function() {
   return (this.getActivity('session') > 0 ? this.getActivity('session') : 0);
}

// returns number of seconds since this session started
VisitorProfile.prototype.sessionTimer = function() {
  return ((this.timestamp - this.getSession()) / 1000);
}

VisitorProfile.prototype.getVersion = function() {
   return this.getActivity('version');
}


/**
 * OrgInfo provides org status and type
 **************************************************/

VisitorProfile.prototype.OrgInfo = {

  // read the oinfo cookie
   cookieData : VisitorProfile.prototype.getBase64Cookie('oinfo'),

   getStatus : function() {
     return getArgs('status',this.cookieData).toUpperCase();
   },

   getType : function() {
     var values = ['TE','PE','EE','DE','ME','UE'];
     var orgType = getArgs('type',this.cookieData);
     return values[orgType];
   }
}

/**
 * WebCmp provides driver and campaign member id
 **************************************************/

VisitorProfile.prototype.WebCmp = {

  // read the webcmp cookie
   cookieData : VisitorProfile.prototype.getBase64Cookie('webcmp'),

   getDriver : function() {
     var driver = getArgs('d',this.cookieData);
     return (driver != null ? driver : '');
   },

   getCampaignMemberId : function() {
     var campaignMemberId = getArgs('cm',this.cookieData);
     return (campaignMemberId != null ? campaignMemberId : '');
   }
}


/**
 * Methods for handling profile details
 **************************************************/

VisitorProfile.prototype.getProperty = function(propertyName) {
  // always return an empty string instead of a null
  // so we can safely print back to form values easily
  if (this.profileData != null) {
     return (this.profileData[propertyName] != null ? this.profileData[propertyName] : '');
   } else {
     return '';
   }
}

// this is typically an array
VisitorProfile.prototype.getProductInterests = function() {
  return this.getProperty('pi');
}

// and this is a string
VisitorProfile.prototype.getPrimaryProductInterest = function() {
   return this.getProperty('ppi');
}

VisitorProfile.prototype.getUserSalutation = function() {
   return this.getProperty('sal');
}

VisitorProfile.prototype.getUserFirstName = function() {
   return this.getProperty('f');
}

VisitorProfile.prototype.getUserLastName = function() {
   return this.getProperty('l');
}

VisitorProfile.prototype.getUserEmail = function() {
   return this.getProperty('e');
}

VisitorProfile.prototype.getUserTitle = function() {
   return this.getProperty('t');
}

VisitorProfile.prototype.getCompanyName = function() {
   return this.getProperty('c');
}

VisitorProfile.prototype.getCompanyCity = function() {
   return this.getProperty('ct');
}

VisitorProfile.prototype.getCompanyState = function() {
   return this.getProperty('st');
}

VisitorProfile.prototype.getCompanyCountry = function() {
   return this.getProperty('cn');
}

VisitorProfile.prototype.getCompanyPostalCode = function() {
   return this.getProperty('pc');
}

VisitorProfile.prototype.getCompanyEmployees = function() {
   return this.getProperty('emp');
}

// now instantiate it
var vp = new VisitorProfile();

/**
 * WebPage Properties
 * @author: jburbridge
 * @since: w156.6
 ************************************************/

function WebPage(pageName) {

  this.name           = pageName;
  this.formType       = '';
  this.driver         = convert15To18(getParam('d'));
  this.nameCaptureId  = '';
  this.locale         = 'us';
  this.hasForm        = false;
  this.isConfirmation = false;
  this.isFramed       = (top != self);
  this.isAloha        = false;
  this.isLogin        = false;

  this.loadPageDetails();

}

WebPage.prototype.setName = function(pageName) {
  if (pageName == null || pageName.length < 1) {
     pageName = new String(document.location.pathname);
  }
  if(pageName.indexOf('/') > -1){
    pageName = pageName.replace(/\//g,":");
    pageName = pageName.replace(/\:index\.jsp/,"");
    pageName = pageName.replace(/\.jsp/,"");
    pageName = ( pageName.match(/\:\w{2}\:/) ? "SFDC" : "SFDC:us" ) + pageName;
  }
  this.name = pageName;
}

WebPage.prototype.loadPageDetails = function() {

  // set the pagename if it hasn't been set yet
  if (this.name == null || this.name == "") {
    this.setName();
  }

  // login pages are special
  if (this.name.match(/SFDC\:\w{2}\:login/)) {

    this.isLogin = true;

  } else {

    // check if the page has a valid leadgen form
    // set the form type based on the path
    // collect driver and namecapture from hidden fields
    for (i in document.forms) {
      f = document.forms[i];
      if (null != f.name && ("reg_form" == f.name || "signup_form" == f.name)) {
        try {

          this.formName = f.name;
          this.hasForm = true;

          // first check if we're in the form directory
          if (this.name.indexOf(':form:') != -1) {

            var regex = /\:form\:(\w+)\:/;
            var matches = this.name.match(regex);
            if (matches != null) {
              this.formType = matches[1];
            }

          // or the in the events directory
          } else if (this.name.indexOf(':events:') != -1) {

            var regex = /\:events\:(\w+)\:/;
            var matches = this.name.match(regex);
            if (matches != null) {
              this.formType = matches[1];
            }

          // or in the consulting partners directory
          } else if (this.name.indexOf(':consulting-partners:') != -1) {
            this.formType = 'consulting-partners';

          }

          // if none of the above
          if (this.formType == '') {
            this.formType = 'other: ' + this.name;
          }

          // get the default driver if it isn't in the URL
          if (this.driver == null) {
            var params = ["DefaultDriverCampaignId", "DefaultDriverId"];
            for (d in params) {
              if (f.elements[params[d]] != null) {
                this.driver = convert15To18(f.elements[params[d]].value);
                break;
              }
            }
          }

          // get the namecapture campaign id
          var nc = "FormCampaignId";
          if (f.elements[nc] != null) {
            this.nameCaptureId = convert15To18(f.elements[nc].value);
          }

        } catch (err) {
          if (Server.isStage()) {
            alert(err);
            throw err;
          }
        }
        break;
      }
    }

    // check if the page is a confirmation page
    if ((this.name.indexOf(':conf:') != -1) ||
        (document.location.pathname.indexOf('_conf.jsp') != -1) ||
        (document.location.pathname.indexOf('leadcapture/SignupServlet') != -1)) {
      this.isConfirmation = true;
    }

  }

  // set the locale
  var matches = this.name.match(/\w{4}\:(\w{2})\:/);
  if (matches != null) {
    this.locale = matches[1];
  }

  // check if the page is aloha from cookie
  this.isAloha = (this.getAloha() == 'true' || this.getAloha() == 'random');
}


WebPage.prototype.getAloha = function() {
  return ((Aloha.cookieValue != null && Aloha.cookieValue != 'null') ? Aloha.cookieValue : 'false');
}

WebPage.prototype.getDriver = function() {
  return (this.driver != null ? this.driver : '');
}

WebPage.prototype.getLocale = function() {
  return (this.locale != null ? this.locale : '');
}

WebPage.prototype.getNameCaptureId = function() {
  return (this.nameCaptureId != null ? this.nameCaptureId : '');
}

WebPage.prototype.getFormType = function() {
  return (this.formType != null ? this.formType : '');
}



/**
 * Omniture v3 Implementation
 * @author: jburbridge
 * @since: w156.3
 ************************************************/
function OmnitureSetup(pageName) {

  /* reporting suite definitions */
  var rsStage          = 'salesforcedev2'; // staging suite
  var rsLogin          = ',salesforcelogin'; // login suite
  var rsUsers          = ',salesforcecurollup'; // customer suite
  var rsNonUsers       = ',salesforcencrollup';  // non-customer suite
  var rsAloha          = ',salesforcealoha'; // aloha opt-in suite
  var rsAloha2         = ',salesforcealoha2'; // aloha random suite

  this.account          = 'salesforceall'; // default suite
  this.customer         = 'noncustomer';
  this.page             = new WebPage(pageName);
  this.formType         = this.page.getFormType();
  this.campaign         = this.page.getDriver();
  this.transactionId    = vp.WebCmp.getCampaignMemberId();
  this.state            = vp.getCompanyState();
  this.country          = vp.getCompanyCountry();
  this.productInt       = vp.getPrimaryProductInterest();
  this.orgStatus        = vp.OrgInfo.getStatus();
  this.visitorType      = vp.getType();
  this.profileVersion   = vp.getVersion();

  // serving content on stage or prod?
  if (Server.isStage()) {
    this.account = rsStage;
  }

  // login page?
  if (this.page.isLogin) {
    this.account += rsLogin;
  } else {
    // customer vs non-customer settings
    if (vp.isCustomer()) {
      this.account += rsUsers;
      this.customer = 'customer';
    } else {
       this.account += rsNonUsers;
    }
    // detect if aloha page
    if (this.page.getAloha() == 'true') {
       this.account += rsAloha;
    } else if (this.page.getAloha() == 'random') {
       this.account += rsAloha2;
    }
  }

  // save the form type to a cookie so we can read it back
  // from the confirmation page
  if (this.page.hasForm) {

    var cookiejar = new CookieHandler();
    cookiejar.setCookie('webform',escape(this.formType));

  // load the formType from a cookie if this is the confirm page
  } else if (this.page.isConfirmation) {

    var cookiejar = new CookieHandler();
    this.formType = unescape(cookiejar.getCookie('webform'));
    cookiejar.deleteCookie('webform');

  }

}

OmnitureSetup.prototype.setPageName = function(pageName) {
  try {
    this.page.setName(pageName);
  } catch (err) {
    if (Server.isStage()) {
      throw ('Exception setting pageName to "' + pageName + '"');
    }
  }
}

OmnitureSetup.prototype.getFormType = function() {
  return ( this.formType!=null ? this.formType : '' );
}

OmnitureSetup.prototype.getAloha = function() {
   return this.page.getAloha();
}

OmnitureSetup.prototype.getAccount = function() {
   return this.account;
}

OmnitureSetup.prototype.getPageName = function() {
   return this.page.name;
}

OmnitureSetup.prototype.getLocale = function() {
   return this.page.getLocale();
}

OmnitureSetup.prototype.getCustomer = function() {
   return this.customer;
}

OmnitureSetup.prototype.getVisitorType = function() {
   return this.visitorType;
}

OmnitureSetup.prototype.getState = function() {
   return this.state;
}

OmnitureSetup.prototype.getCountry = function() {
   return this.country;
}

OmnitureSetup.prototype.getProductInterest = function() {
   return this.productInt;
}

OmnitureSetup.prototype.getCampaign = function() {
  // if the driver isn't on the url or the page, try to get it from the cookie
  return (this.campaign ? this.capaign : vp.WebCmp.getDriver());
}

OmnitureSetup.prototype.getTransactionId = function() {
   return this.transactionId;
}

OmnitureSetup.prototype.getNameCaptureId = function() {
   return this.page.getNameCaptureId();
}



function equalCols(leftCol,rightCol,paddingVal){
  var l = document.getElementById(leftCol);
  var r = document.getElementById(rightCol);
  var newHeight = 0;
if (null != paddingVal)
{
  newHeight = l.offsetHeight + paddingVal;
}else{
 newHeight = l.offsetHeight;
}

  r.offsetHeight >= l.offsetHeight ? l.style.height = r.offsetHeight + "px" : r.style.height =  newHeight + "px";
}

/*
 * Aloha BETA Site Session Management
 * remove after March 16, 2009
 * @author: jburbridge
 * @since: w158.1
 ************************************************/

var Aloha = {

  cookieValue : VisitorProfile.prototype.getCookieData('isAloha'),

  // is aloha mode turned on?
  isOn : function () {
    return (this.cookieValue  == "true" || this.cookieValue == "random");
  },

  // shorthand to set the cookie
  setAloha : function (cookieValue) {
    this.cookieValue = cookieValue;
    var cookiejar = new CookieHandler();
    cookiejar.setCookie('isAloha', this.cookieValue, 60*60*24*90); // 90 days
  },


  // renews the cookie
  renew : function () {
    // fake sticky browser session
    if ((this.cookieValue == 'true') && (vp.idle >= 30*60) &&
        (document.referrer.indexOf('salesforce.com') != -1)) {
      this.cookieValue = 'false';
    }
    this.setAloha(this.cookieValue);
    return this.cookieValue;
  },

  // flips the value on/off
  toggle : function() {
    this.cookieValue = (this.isOn() ? "false" : "true");
    return this.renew();
  },

  // reset everything
  nuke : function () {
    this.cookieValue = '';
    var cookiejar = new CookieHandler();
    cookiejar.deleteCookie('isAloha');
  },

  // returns true given a certain percentage chance, ie:
  // randomBoolean(33) returns true 1 out of 3 times on average
  randomBoolean : function (percentChance) {
    var resolution = 1000;
    return (Math.floor(Math.random()*(100 * resolution)) <= percentChance * resolution);
  },

  // this sets a new cookie to 'false' or 'random' based on visitor profile and
  // whether this is the first time we are seeing them on the homepage
  setRandomAloha : function () {
    if (this.cookieValue == null) {
      this.cookieValue = 'false';
      // randomize anonymous visitors from the us homepage only
      if (document.location.pathname == '/') {
        if (vp.getType() == 'anonymous' && this.randomBoolean(25)) {
          this.cookieValue = 'random';
        }
      }
      this.setAloha(this.cookieValue);
    }
  }
}
