///// utils.js ///////
// Copyright 2000-2007, Newsfutures, Inc. All Rights Reserved.
// Confidential and Proprietary Information of Newsfutures, Inc.
// %Z%%M%, %I%, %G%

/* default init function does nothing */    
function init() { }

function doNothing() {}

function handleUnload() {}
function handleKeyDown(ev) { return true;}

function theTime() {
  var d = new Date();
  var minutes = d.getMinutes();
  if (minutes < 10) { minutes = "0" + d.getMinutes() +""; }	
  document.write(d.getHours()+ ":" + minutes + "&nbsp;");
}

function roundIt (num, d) {
  // rounds num to d digits and print to document
    document.write(new Number(num).toFixed(d));
}

function roundTo (num, d) {
  // rounds num to d digits, and returns number
  return new Number(num).toFixed(d);
}

function roundPrint (num, dec) {
    var res = (dec > 1) ? (Math.round(num * dec) / dec) : Math.round(num);
    document.write(res);
}

function round (num, dec) {
    return (dec > 1) ? (Math.round(num * dec) / dec) : Math.round(num);
}

function colorMsg (msg, color) {
    return msg ? msg.fontcolor(color) : msg;
}

function stayPut (delay) {
  // waits for <delay> milliseconds
  d = new Date()
  while (1) {
    mill = new Date()
    diff = mill-d
    if (diff > delay) {break;}
  }
}

function confirmDelete(f, what) {
  if (confirm("Are you sure you want to delete this "+what+"?")) {
    f.submit();
  }
}

function confirmAction(f, what) {
  if (confirm("Are you sure you want to "+what+"?")) {
    f.submit();
  }
}

function checkNum(f, name, what) {
  if (isNaN(parseInt(f.elements[name].value, 10))) {
    alert("Invalid "+what);
  } else {
    f.submit();
  }
}

// This function sets the HTML block with id='name' to have the content 'value'.
// It allows block content to be modified from an input object eventHandler 
// (eg.onChange="setBlockById('foo','weather is nice');")
function setBlockById(name, value) {
  document.getElementById(name).innerHTML=value;
}

// shortHand for document.getElementById()
function gebid(id) {
    return document.getElementById(id);
}
// shortHand for document.write()
function dw(s) {
    return document.write(s);
}

// converts a timestamp to iso date and/or time (yyyy-mm-dd hh:mm)
function tsToIsoDateTime(ts, showDate, showTime) {
    var date = new Date();
    date.setTime(ts);
    var res = '';
    var x;

    if(showDate) {
        res += date.getFullYear() + '-';
        x = date.getMonth() + 1;
        res += ((x < 10) ? ('0' + x) : x) + '-';
        x = date.getDate();
        res += ((x < 10) ? ('0' + x) : x);
        if(showTime)
            res += ' ';
    }
    if(showTime) {
        x = date.getHours();
        res += ((x < 10) ? ('0' + x) : x) + ':';
        x = date.getMinutes();
        res += ((x < 10) ? ('0' + x) : x);
    }
    return res;
}

// converts a timestamp to a human readable date (e.g. Mar. 3, 2009) and/or time (yyyy-mm-dd hh:mm)
function tsToDateTime(ts, showDate, showTime) {
    var date = new Date();
    date.setTime(ts);
    var res = '';
    var x;

    if(showDate) {
        res += ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][date.getMonth()] + ". " +
                date.getDate() + ", " +
                date.getFullYear();
        if(showTime)
            res += ' ';
    }
    if(showTime) {
        x = date.getHours();
        res += ((x < 10) ? ('0' + x) : x) + ':';
        x = date.getMinutes();
        res += ((x < 10) ? ('0' + x) : x);
    }
    return res;
}


// parse a date yyyy-mm-dd[ hh:mm[:ss]] to a Date object
// if there's a syntax error, return null
function isoDateToTs(str) {
    try {
        str = trim(str);
        var dt = str.split(" ");
        if((dt.length < 1) || (dt.length > 2))
            return null;
        var ymd = dt[0].split("-");
        if(ymd.length != 3) {
            ymd = dt[0].split("/");
            if(ymd.length != 3)
                return null;
        }
        if(ymd[0] < 1900)
            return null;
        var d = new Date();
        d.setFullYear(ymd[0]);
        d.setMonth(ymd[1]-1);
        d.setDate(ymd[2]);
        if(dt.length == 2) {
            var hm = dt[1].split(":");
            if((hm.length < 2) || (hm.length > 3))
                return null;
            d.setHours(hm[0], hm[1], (hm.length == 3) ? hm[2] : 0, 0);
        } else {
            d.setHours(12,0,0,0);
        }
        return d.getTime();
    } catch(err) {
        return null;
    }
}

// number of secs in a day
var daySecs = 24 * 3600;

// convert a number of millisecs into a time span
function tsToTimeSpan(ts) {
    var res = "";
    ts /= 1000;
    var days = Math.floor(ts / daySecs);
    var hours = Math.floor(ts / 3600) % 24;
    var mins = Math.floor(ts / 60) % 60;
    var secs = Math.floor(ts % 60);

    if(days > 0) {
        if(days > 1) {
            res = days + " days";
        } else {
            res = "1 day";
            if(hours > 0)
                res += " " + hours + " hour" + addPlural(hours);
        }
    } else if(ts < 60) {
        res = secs + " seconds";
    } else {
        if(hours > 0)
            res = hours +  " hour" + addPlural(hours);
        if(mins > 0)
            res += " " + mins + " minute" + addPlural(mins);
        if(ts < 300)
            res += " " + secs + " second(s)";
    }
    return res;
}

function addPlural(n) {
  return (n > 1) ? "s" : "";
}

// trim a string
function trim(s) {
    var i = 0;
    while((i < s.length) && (s.charAt(i) <= ' ')) i++;
    if(i > 0)
        s = s.substr(i);
    i = s.length;
    while((i-- > 0) && (s.charAt(i) <= ' '));
    s = s.substr(0,i+1);
    return s;
}

// put double quotes around 's' and replace any dblquote in s with &quot;
function strQuote(s) {
    return '"' + s.replace('"', '&quot;') + '"';
}

// put apostrophes (single quotes) around 's' and replace any apostrophes in s with &apos;
function strApos(s) {
    return "'" + s.replace("'", "&apos;") + "'";
}

// true iff str startsWith stem
function startsWith(str, stem) {
    if(!(str && stem)) return false;
    var stemLen = stem.length;
    if(str.length < stemLen) return false;
    return str.substring(0,stemLen) == stem;
}

////////////////////////
// simple stringbuffer implementation
////////////////////////

function StringBuffer() {
    this.buffer = [];
}
StringBuffer.prototype.append = function(string) {
    this.buffer.push(string); return this;
}
StringBuffer.prototype.undo = function() {
    return this.buffer.pop();
}
StringBuffer.prototype.pop = function(str) {
    var p = this.buffer.pop();
    if((p != str) && (p != undefined)) {
        this.buffer.push(p);
        return true;
    }
    return false;
}
StringBuffer.prototype.toString = function() {
    return this.buffer.join("");
}

/////////////////////////
// Rotate an array in a way that seems random, but is repeatable if 'seed' remains the same.
// This is meant to be used with the reading user's ID as seed so that info is shown in different
// order to different users, but in a constant way to each user.
/////////////////////////
function randomRotate(arr, seed) {
    var rotIdx = Math.round(Math.exp(20+seed)) % arr.length;
    return arr.slice(rotIdx, arr.length).concat(arr.slice(0, rotIdx));
}

//////////////
// Randomize an array's contents based on a 'seed'. Ie. using the same seed and the same 'arr', always
// get the same resulting order.
//////////////
function randomize(arr, seed) {
    var tmp = [];
    while(arr.length > 0) {
        var idx = (seed++ * 510511) % arr.length;
        tmp.push(arr[idx]);
        arr.splice(idx,1);
    }
    for(var n = tmp.length ; n-- > 0 ; arr.push(tmp[n]));
}


////////////////////////
// Cookie handling
////////////////////////

function setCookie(name,value,days) {
    if(!days)
        days = 100000;
    var date = new Date();
    date.setTime(date.getTime()+(days*24*60*60*1000));
    var expires = "; expires="+date.toGMTString();
    document.cookie = name+"="+value+expires+"; path=/";
}

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

function getCookie(name) {
    var res = "";
    if(document.cookie.length> 0) {
	var start = document.cookie.indexOf(name + "=")
	if(start > -1) {
	    start = start + name.length + 1;
	    var end = document.cookie.indexOf( ";", start);
	    if(end == -1)
            end = document.cookie.length;
	    res = unescape(document.cookie.substring(start, end));
	} 
    }
    return res;
}


////////////////////////
// simple screen messaging system
////////////////////////
    
function setMsg(msg) {
    gebid('msgBox').innerHTML = msg;
}
function addMsg(msg) { 
    gebid('msgBox').innerHTML += msg;
}
function clearMsg() {
    gebid('msgBox').innerHTML = "";
}
function hasMsg() {
    return gebid('msgBox').innerHTML != "";
}

// simple errors: for now popup msg
function error(msg) {
    window.alert(msg);
}

////////////////////
// Highlight a DOM object temporarily by setting its background to red,
// then progressively to white and finally transparent.
////////////////////
function highlight(elId) {
    setTimeout("highlight0('" + elId + "',32)", 100);
}

function highlight0(elId, color) {
    var el = document.getElementById(elId);
    if(color >= 256) {
	el.style.backgroundColor = "transparent";
    } else {
	el.style.backgroundColor = "#FF" + color.toString(16) + color.toString(16);
	setTimeout("highlight0('" + elId + "'," + (color+40) + ")", 100);
    }
}

///////////////////////////////
// Lookup words in the 'terms' dict and return or write the localized name.
//////////////////////////////
var terms = {};

function writeTerm(term) {
    document.write(xlateTerm(term));
}

function xlateTerm(term) {
    var c0 = term.charAt(0);
    var capitalize = (c0 >= 'A') && (c0 <= 'Z');
    var s = terms[term.toLowerCase()];
    if(s == null) return term;
    if(capitalize)
	s = s.substring(0,1).toUpperCase() + s.substring(1);
    return s;
}

////////////////////////////////////////////////////////////
function popProfile (login) {
   // Pops up a user's public profile
    var url = "/f/user/publicProfile.html?login=" + login + "&cSym=&format=pop";
    window.open(url,'_blank','scrollbars=yes,status=no,width=500,height=500,top=50,left=50');
    return false;
}

function popProfileFr (login) {
   // Pops up a user's public profile (french version)
    var url = "/f/fr/user/publicProfile.html?login=" + login + "&cSym=&format=pop";
    window.open(url,'_blank','scrollbars=yes,status=no,width=500,height=500,top=50,left=50');
    return false;
}

// check if an object used as an associative array is empty
function isObjEmpty(obj) {
    for(var k in obj) {
        return false;
    }
    return true;
}

// count the number of entries in an object
function objSize(obj) {
    var size = 0;
    for(var k in obj)
        size++;
    return size;
}
////////////// Resizable IFRAME
function genNFIFrameHTML(frameId, w, h, src) {
    var s = "[<a href='javascript:NFIFrameGrow(\"" + frameId + "\", 0, 50)'>+</a>] " +
	"[<a href='javascript:NFIFrameGrow(\"" + frameId + "\", 0, -50)'>-</a>]<br>" +
	"<iframe id='" + frameId + "' src='" + src + "' width=" + w + " height=" + h + ">"; 
    return s;
};

function NFIFrameGrow(fid, deltaWidth, deltaHeight) {
    var el = document.getElementById(fid);
    el.height =  deltaHeight + (1 * el.height);
    el.width = deltaWidth + (1 * el.width);
}

// create an <option> tag like this:
//	<option value="val" selected>label<option>
// the 'selected' attribute is set only if val==setVal
//
function appendOption(sb, val, label, selVal) {
    sb.append('<option value="' + val + '" ' + ((val == selVal) ? 'selected' : '') + '>' + label + '</option>');
}

//// stickies
// Invoke StickiesMgr.setStickyDiv(divId [,top [,width]] )
// it will make the element 'divId' stick to the top of the screen rather than be scrolled off.
// ATTENTION: the element 'divId' should be found in another div that does nothing but wraps divId (it will act
// as a place holder when divId is made to float at the top of the screen.
// Two optional args:
//  top: where should it get stuck at the top (i.e. if there is already something to get stuck at the top,
//       get stuck below that.
//  width: specify a with that is not the natural width of the div (e.g. "100%" for a menubar or "150px" for some
//         data box.)

function Stickies() {}
var StickiesMgr = new Stickies();

// make a div stick to the top of the screen if scrolled out
Stickies.prototype.setStickyDiv = function(divId, top, width) {
    if(this.stickies == undefined) {
        if( window.addEventListener ) {
            window.addEventListener('scroll', StickiesMgr.checkStickies,false);
        } else if( document.addEventListener ) {
            document.addEventListener('scroll',StickiesMgr.checkStickies,false);
        }
        this.stickies = {};
    }
    var div = gebid(divId);
    this.stickies[divId] = {
        parent: div.parentNode,
        div: div,
        stuckTop: (top == undefined ? 0 : top),
        width: width
    }
}

Stickies.prototype.getAbsPos = function(el) {
    var pos = [0,0];
    while( el != null ) {
        pos[0] += el.offsetLeft;
        pos[1] += el.offsetTop;
        el = el.offsetParent;
    }
    return pos;
}

// called whenever page is scrolled to check what needs to be stuck or unstuck
Stickies.prototype.checkStickies = function() {
    var curScroll = document.body.scrollTop;
    for(var divId in StickiesMgr.stickies) {
        var info = StickiesMgr.stickies[divId];
        var regPos = StickiesMgr.getAbsPos(info.parent);
        if(regPos[1] < (curScroll + info.stuckTop)) {
            if(!info.isStuck) {
                var style = info.parent.style;
                style.width = info.div.scrollWidth; 
                style.height = info.div.scrollHeight;
                style = info.div.style;
                style.position="fixed";
                style.top = info.stuckTop;
                style.left = regPos[0];
                style.width = (info.width ? info.width : info.div.scrollWidth);
                info.isStuck = true;
            }
        } else {
            if(info.isStuck) {
                info.parent.style.width = "";
                info.parent.style.height = "";
                info.div.style.position = "static";
                info.div.style.width = "";
                info.isStuck = false;
            }
        }
    }
}

//////////// YUI HTML Editor pop-up

/**
 * To open an HTML editor in a popup browser window, do this:
 *      editWithRTE(elId, {width: 500, height:200, title: 'HTML Editor')  // found in js/utils.js
 * Where:
 *   elId: the 'id' of the TextArea element
 *   width: the width of the editor (in pixels)
 *   height the desired height of the editor (in pixels)
 * When the user presses 'Save' in the popup window, the textArea in the opener window is
 * automatically updated.
 */
function editWithRTE(elId, args) {
    if(args.width == undefined) args.width=500;
    if(args.height == undefined) args.height=400;
    window.open("/f/util/RTE.html?elId=" + elId + "&width=" + args.width + "&h=" + args.height,
            "htmlEditor",
            "location=0,menubar=0,statusbar=0,toolbar=0,resizable=1");
}


///// siteDefs.js ////
// Copyright 2000-2008, Newsfutures, Inc. All Rights Reserved.
// Confidential and Proprietary Information of Newsfutures, Inc.

var siteDefs = {
  dollarsSymbol: "$",
  dollarsSymbolBefore: true,
  centSymbol: "&#162;",
  siteName: "predipol.newsfutures.com"
}


///// logsec.js //////
// Copyright 2000-2007, Newsfutures, Inc. All Rights Reserved.
// Confidential and Proprietary Information of Newsfutures, Inc.
// %Z%%M%, %I%, %G%


function setJSL(login) {
    setCookie("ptsJSL", escape(login.toLowerCase()));
}

// this is the method used when login in from a login or registration form. It adds a '?' in front to 
// make it tentative when checking with psl
function setJSLFromFld(fldName) {
    setJSL('?' + document.getElementById(fldName).value);
}


// when submitting logout request, clear ptsJSL 
function clearJSL() {
    deleteCookie("ptsJSL");
}


// in all pages call checkPSL().
// It makes sure that either $user.id is empty, i.e. not logged in, or that $user.id == the JSL cookie
// set using setJSL().
// If the assumptions above are true, it returns, otherwise we assume a page switch and the browser is redirected
//  to the special page:
//   /error/switched.html?cmd=UserMgr.report&what=switch&jsl=<getCookie(ptsJSL)>&psl=<$user.login> 
// which records the problem and redirects to /index.html.
function checkPSL() {
    // if not logged in, there is no need to check
    var psl = "";
    if(psl == "")
        return;

    // get value of ptsJSL cookie or "" if not set
    var jsl = getCookie('ptsJSL');

    // if psl and jsl are the same, all is well
    if(psl == jsl)
        return;

    // if we get here, we have a problem, clear everything and go back to the index page
    // logout the user 
    deleteCookie("ptsJSL");
    deleteCookie("ptsLogin");

    // redirect to the error page and record the problem
    if(true) {
        window.location =
        "/f/error/switched.html" +
        "?cmd=UserMgr.report" +
        "&what=userSwitched" +
        "&jsl=" + encodeURIComponent(jsl) +
        "&psl=" + encodeURIComponent(psl);
    } else {
        alert("SWITCHED: jsl=" + jsl + "  psl=" + psl);
    }
}    



///// realMoney.js ///
// Copyright 2000-2008, Newsfutures, Inc. All Rights Reserved.
// Confidential and Proprietary Information of Newsfutures, Inc.

function cents (cents) {
    document.write(toCents(cents));
}

function toCents (cents) {
    return cents + 'F';
}

function dollars (cents) {
    document.write(toDollars(cents));
}

function toDollars (cents) {
    return toCents(cents);
}




///// ajax.js ////////
/**
 * Various Ajax utilities.
 */

/**
 * return and XMLHttpRequest object, or null if not supported.
 */
function getAjaxRequestor() {
    var request;
    if(window.XMLHttpRequest) {
	//Mozilla-based browsers
        request = new XMLHttpRequest();
    } else if(window.ActiveXObject) {
	// IE stuff
        request=new ActiveXObject("Msxml2.XMLHTTP");
        if(!request) {
            request=new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
    return request;
}

/**
 * Prepare a request. This always uses GET and makes asynch requests
 * Params. All you need to do is to call 'send()' on the request:
 *      request: the HttpRequest to use (onreadystatechange must be set before this call)
 * 	url: the URL to query
 *	args: as dict of key/value pairs representing optional args
 * 	handler: the response handler
 */
function makeAjaxRequest(request, url, args, handler) {
    if(args) {
        url += "?";
        for(var k in args)
            url += k + "=" + encodeURIComponent(args[k]) + "&";
    }
    var argSep =
    url += ((url.indexOf('?') >= 0) ? "&" : "?") + "rndAjaxArg=" + Math.random();

    request.onreadystatechange = handler;
    request.open('GET',url,true);
    request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
    request.send("");
}

// make sure AJAX is available, otherwise redirect to /f/login/noajax.html
function testAjax() {
    if(!getAjaxRequestor()) 
	window.location = "/f/login/noajax.html";
}

/**
 * Same as makeAjaxRequest, but use POST instead.
 */
function postAjaxRequest(request, url, args, handler) {
    var sb = new StringBuffer();
    if(args) {
        for(var k in args)
            sb.append(k + "=" + encodeURIComponent(args[k]) + "&");
    }
    request.onreadystatechange = handler;
    request.open('POST',url,true);
    request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
    request.send(sb.toString());
}

// does the standard checks needed by all Ajax handlers, plus:
// - if 'head' != undefined check that reply starts with 'head'
// if an error is encountered an alert is printed and false is returned
// return true only if the erply is ready and starts with 'head'
function prepAjaxResp(req, head) {
    if(req.readyState != 4) return false;
    if(req.status != 200) {
        var errMsg = (req.status == 500) ? req.responseText.substring(21) : req.responseText;
        switch(errMsg) {
            default:
                alert("Error: " + errMsg);
        }
        return false;
    }
    if((head != undefined) && !startsWith(req.responseText, head)) {
        var errMsg = (req.responseText.length > 100) ? req.responseText.substring(0,100) + '[...]' : req.responseText;
        alert("An error occured: " + errMsg);
        return false;
    }
    return true;
}


