// Copyright thinkingap.com
//

// Please ensure the oceanTrim() method is defined at the top
// the startup code of this page code relies on this ordering.



// Function to trim off any unwanted spaces from the start or end of variables
function webflowTrim(trimMe) {

    // get rid of silly cases first
    if ( trimMe === undefined ) { return null; }
    if ( trimMe === null ) { return trimMe;}
    if ( trimMe === '' ) { return trimMe; }

    // Get rid of the whitespaces at the start
    var padLength = 0;
    while ( trimMe.charAt(padLength) == ' ' ) {
    
        padLength = padLength + 1;
        
    }
    
    if ( padLength > 0 ) {
    
        trimMe = trimMe.substring(padLength);
        
    }
    
    // Get rid of the whitespaces at the end
    var endIndex = trimMe.length - 1;
    var len      = endIndex;
    while ( trimMe.charAt(endIndex) == ' ' ) {

        endIndex = endIndex - 1;
      
    }

    if ( endIndex < len ) {

        trimMe = trimMe.substring(0, endIndex + 1);

    }
    
    // get rid of the silly 0xA0 character that appears when we do nodeValue on a lv column
    if ( trimMe.length > 0 ) {
        if ( trimMe.charCodeAt( 0 ) === 160 ) {
            trimMe = trimMe.substring( 1 );
        }
    }

    return trimMe;

}

// PUBLIC
// trims a given string from left / right padded whitespaces
function oceanTrim(trimMe) {
    return webflowTrim(trimMe);
}


// PUBLIC
// Use this method to get element reference by name
// Example : INPUT id="myInputTag"....
// then use :
// var inputTagRef = oceanGetElementById( "myInputTag" );
// returns null if no such element with given ID found
function oceanGetElementById( id ) {

    var objRef = document.getElementById( id );
    // Ensure such an element exists
    if ( objRef === null ) {
      return null;
    }

    // setup our default result
    var retArr = [];

    // get list of all elements on page that are of the same tag type
    var objTagName = objRef.tagName;
    var allElements = document.getElementsByTagName( objTagName );
    var allEleLen = allElements.length;

    // loop through this list looking for elements 
    // that have the same ID as that was given
    for ( var i = 0 ; i < allEleLen ; i = i + 1 ) {

        var nextEle = allElements[ i ];

        // see if next element has the same ID 
        // property value as that given
        if( nextEle.getAttribute( "id" ) == id ) {

            retArr.push( nextEle );

        }

    } // end-for

    if ( retArr.length > 1 ) {

        return retArr;

    }

    return objRef;

}
 


// PUBLIC
// checks to see if given string argument represents an integer
function isInteger(arg) {

    var arr = arg.match(/\d+/);
    
    if ( arr === null ) { return false; }
    
    if ( arr.length > 1 ) { return false; }

    if ( arr.length < 1 ) { return false; }
    
    arr = arr[0];
    
    if ( arg == arr ) { return true; }
    
    return false;

}



// PUBLIC
// Given a cookie name returns its value or blank if it does not exist.
function oceanGetCookie( cookieName ) {

    // get the cookie value
    var cookieVal = document.cookie;
    var cookieLen = cookieVal.length;

    // Find start index;
    var start = cookieVal.indexOf( cookieName + "=" );
    if (start==-1) { return ""; }
    start = start + cookieName.length;

    // Find end index;
    var end = cookieVal.indexOf(";", start);

    if (end==-1) { end = cookieLen; }

    // Blank values dont have an equals sign
    if (start==end) {return "";}

    // Unescape the sequence
    cookieVal = cookieVal.substring(start+1,end);
    cookieVal = unescape( cookieVal );

    return cookieVal;

}

// PUBLIC
// Sets a cookie value in the global scope, use to pass values between windows.
function oceanSetCookie( cookieName, cookieValue, forever ) {

    // escape the value
    cookieValue = escape( cookieValue );

    if ( forever === undefined || forever === null ) {

       document.cookie = cookieName + "=" + cookieValue + "; path=/";

    } else {

       document.cookie = cookieName + "=" + cookieValue + ";expires=Friday, 01-Jan-2999 00:00:00 GMT;path=/";

    }

}



// look for the eldest window
function oceanCache_getEldestWindow() {

    // keep looking for eldest window
    var seed = top;
    while ( seed.opener !== undefined && seed.opener !== null ) {

        // stop when opener was never defined or is closed
        if ( seed.opener.closed === true ) {

            break;

        }

        seed = seed.opener.top;

    }

    return seed;

}

// PRIVATE
// Create empty store on window
function private_oceanCache_createStore() {

    window._oceanCache = {};

}


// PUBLIC
// Global variable store
// pass variable name and value
// the variable is only ever defined once in the eldest window
function oceanCacheSet( varname, varval ) {

    // get reference to eldest window
    var winRef = oceanCache_getEldestWindow();

    // ensure the global store is defined in eldest window
    if ( typeof( winRef._oceanCache ) == 'undefined' ) {

        winRef.private_oceanCache_createStore();

    }

    // declare and set variable
    winRef._oceanCache[ varname ] = varval;

}


// PUBLIC
// Global variable cache
// get value associated with this variable
function oceanCacheGet( varname ) {

    // get reference to eldest window
    var winRef = oceanCache_getEldestWindow();

    // ensure the global store is defined in eldest window
    if ( typeof( winRef._oceanCache ) == 'undefined' ) {

        winRef.private_oceanCache_createStore();

    }

    // return dictionary value
    return winRef._oceanCache[ varname ];

}





// Determine browser
// can be either of :
// ie
// netscape
// mozilla
// opera
// defaults to 'unknown' for any other type
var ocean_browser = window.navigator.appName.toLowerCase();
if ( ocean_browser.indexOf("microsoft internet explorer") != -1 ) {

    ocean_browser = "ie";

}
else if ( ocean_browser.indexOf("netscape") != -1 ) {

    ocean_browser = "mozilla";

    var userAgentStr = window.navigator.userAgent.toLowerCase();
    
    if ( userAgentStr.indexOf( "navigator" ) != -1 ) {
    
        ocean_browser = "netscape";
        
    } else if ( userAgentStr.indexOf( "chrome/" ) != -1 ) {

        ocean_browser = "chrome";

    } else if ( userAgentStr.indexOf( "firefox/" ) != -1 ) {

        ocean_browser = "firefox";

    } else if ( userAgentStr.indexOf( "safari/" ) != -1 ) {

        ocean_browser = "safari";

    }
    
}
else if ( ocean_browser.indexOf("opera") != -1 ) {

    ocean_browser = "opera";

}
else {

    ocean_browser = "unknown";

}

// further try and obtain browser version
// so far, only doing this for IE
var ocean_browser_version = "";
if ( ocean_browser == 'ie' ) {

    var ocean_browser_version_temp = window.navigator.appVersion;
    ocean_browser_version_temp = ocean_browser_version_temp.split( ";" );
    if ( ocean_browser_version_temp.length > 1 ) {

        ocean_browser_version_temp = ocean_browser_version_temp[ 1 ];
        ocean_browser_version_temp = oceanTrim( ocean_browser_version_temp );
        if ( ocean_browser_version_temp.indexOf( "MSIE" ) === 0 ) {
            if ( ocean_browser_version_temp.length > 5 ) {
                ocean_browser_version = ocean_browser_version_temp.substring( 5 );
            }
        }

    }

}

// PUBLIC
// Checks to see if the user is currently logged into Ocean or not
// Useful at public pages
// Returns boolean true / false
function oceanIsUserLoggedIn() {

    // get the Ocean secure cookie
    var secureId = oceanGetCookie( "OCEANSECUREID" );
    secureId = oceanTrim( secureId );
    if ( secureId === '' ) {

        // if secure id is empty, that means is not logged in
        return false;

    }

    // is logged in
    return true;

}


// PUBLIC
// Invoke this method to properly log out of your Ocean application.
// The second parameter is optional and is not encouraged.
// The second parameter optionally has the page route to the given url
// Otherwise the default behaviour is to route to "/"
function oceanLogout( optionalLogoutUrl ) {

    if ( optionalLogoutUrl === undefined || optionalLogoutUrl === null ) {
        optionalLogoutUrl = "";
    }
    optionalLogoutUrl = oceanTrim( optionalLogoutUrl );

    // LOG OUT
    oceanSetCookie( "OCEANSECUREID" , "" );

    // see if programer specified a logout url
    var logoutUrl = "/";
    if ( optionalLogoutUrl !== '' ) {

        logoutUrl = optionalLogoutUrl;

    }

    // goto the logout url
    top.location = logoutUrl;

}




// PUBLIC
// attach a method pointer whenever "eventName" fires
// DEPRECATED - SEE BELOW
function oxxxceanAttachEvent(eventName, fPtr) {

    return attachEvent(eventName, fPtr);

}


// PUBLIC
// detach a previously attached method pointer from "eventName"
// DEPRECATED - SEE BELOW
function oxxxceanDetachEvent(eventName, fPtr) {

    detachEvent(eventName, fPtr);

}


// PRIVATE
// method to test if given window handle is closed
// the arg parameter should be the string name of the window
function oceanIsWindowClosed( arg ) {

    try {

        eval( "var t = " + arg + ".parent" );

    }
    catch(e) {

        return true;

    }
    
    // doing only this much does not work on safari
    // let's do an extra straightforward check - just ask if it's closed !
    arg = eval( arg );
    if ( arg.closed === true ) {

        return true;

    }

    return false;
    
}



// Lock for monitoring use of ocean channel
// In the future we should introduce many channels.
var oceanParent = null;
if(typeof(top.opener)!='undefined' && typeof(top.opener)!='unknown' ) {
    try {
        //if (!top.opener.closed) {
        if ( oceanIsWindowClosed("top.opener") === false ) {
            oceanParent = top.opener;
        }
    }
    catch(e) {}
}

// checks to see if a window's parent exists
function oceanParentExists() {
    if (typeof(oceanParent)!='unknown' && typeof(oceanParent)!='undefined' && oceanParent !== null && !oceanParent.closed) {
        return true;
    }
    return false;
}


if (!window.oceanChannel) {
    var oceanChannel="free";
    var oceanTimeout = 100;
    var oceanTimeoutCounter = 0;
}

//var oceanExecTimeOutId = null;

// INTERNAL
function oceanTimedOut() {
    if (oceanTimeoutCounter > oceanTimeout) {
       return true;
    } else {
        return false;
    }
}

// INTERNAL
function oceanClearChannel() {
    oceanTimeoutCounter = 0;
    oceanChannel = "free";
}

// General client triggerred execution on ocean
function oceanExec(jspCmd, jspArgs, callBack, viewFrame, dataFrame, arrResult) {

    if ( viewFrame === undefined || viewFrame === null ) {
        viewFrame = "";
    }
    if ( dataFrame === undefined || dataFrame === null ) {
        dataFrame = "";
    }
    if ( arrResult === undefined || arrResult === null ) {
        arrResult = "";
    }

    // Ensure channel is free
    if ( oceanChannel == "inuse" ) {

        oceanTimeoutCounter=oceanTimeoutCounter+1;
        if (oceanTimedOut()) {
            window.status = "Server Timed out - Clearing data channel - Please check server log for further information";
            oceanClearChannel();
        }

        var q = "\"";
        var c = ",";
        var cmd = "oceanExec(" + q + jspCmd  + q + c
                              + q + jspArgs + q + c
                              + q + callBack + q + c
                              + q + viewFrame + q + c
                              + q + dataFrame + q + c
                              + q + arrResult + q +")";

        // Try again in a 10th of a second
        setTimeout(cmd, 10);
        return;

   }

    oceanChannel = "inuse";

    // Change cursor to egg timer
    document.body.style.cursor = "wait";

    // So as not to get mixed up with infrastructure args
    jspArgs = jspArgs.replace(/&/g,'`');

    // Do replacement to stop the loss of chars
    jspArgs = jspArgs.replace(/\+/g,'%2B');

    jspArgs = jspArgs.replace(/\?/g,'%3F');


    // Pass the argument to the system file, ensure no caching occurs
    var page = "execute.html";
    if ( arrResult !== undefined && arrResult !== null && arrResult !== '' ) {
        page = "executeArrResult.html";
    }

    var loc = "/sys" + "tem/clientJSP/" + page + ".nocache?jspCmd=" + jspCmd +
                 "&jspArgs="+jspArgs +
                 "&callBack=" + callBack +
                 "&viewFrame=";


    if ( viewFrame !== undefined && viewFrame !== null && viewFrame !== '' ) {
        loc = loc + viewFrame;
    } else {
        loc = loc + "oceanView";
    }

    loc = loc + "&dataFrame=";

    // Execute on ocean
    if ( dataFrame !== undefined && dataFrame !== null && dataFrame !== '' ) {
        loc = loc + dataFrame;
        eval("top."+dataFrame+".location.href = loc");
    }
    else {
        loc = loc + "oceanData";
        parent.oceanData.location.href = loc;
    }

    // BUG FIX : this is to tell oceanGetResult that most recent result is 
    // from an oceanExec() call and not an oceanExecLong() call
    if(window.oceanLongRes) {
        oceanLongRes = "noresult";
    }
        
}


var oceanLongCount=0;
//
// Performas asynch call to ocean
//
// Server param is optional eg: server=195.137.44.150
function oceanExecLong(cmd,params,callback,server) {

    var formRef = document.forms.meform1;

    if ( server === undefined ) {

        formRef.action = "/sys" + "tem/clientJSP/longiframe.html.nocache";
        formRef.oceanUrlForward.value = '';

    }
    else {

        formRef.action = "/sys" + "tem/clientJSP/longiframe_remote.html.nocache";
        formRef.oceanUrlForward.value = server;
    }


    if (!params) { alert("2nd paramter to oceanExecLong no provided"); }
    if (!callback) { alert("3rd paramter to oceanExecLong no provided"); }

    if (params.substring(0,1)=='?') {
        params = params.substring(1);
    }

    privateLog="starting";

    oceanLongCount=oceanLongCount+1;
    var c = oceanLongCount;

    privateLog = privateLog + " ,setting cursor";
    document.body.style.cursor = "wait";

    privateLog = privateLog + " ,writing to div";

    privateLog = privateLog + " ,div written";
    formRef.jspCmd.value   = cmd;
    privateLog = privateLog + " ,1";
    formRef.jspArgs.value  = params;
    privateLog = privateLog + " ,2";
    formRef.callBack.value = callback;
    privateLog = privateLog + " ,3";
    formRef.submit();
    privateLog = privateLog + " ,finished ok";
}





// method that is used to get the result of an oceanExec() call
function oceanGetResult(dataFrame) {
    if(window.oceanLongRes) {
        if(oceanLongRes != "noresult") {
           var temp = oceanLongRes;
           oceanLongRes = "noresult";
           return temp;
        }
    }

        // Change cursor to default.i.e not a egg timer(i.e not busy.)
    //// was originally just : document.body.style.cursor = "default";
    //if(typeof(document)!= "undefined" && typeof(document.body)!= "undefined" && typeof(document.body.style)!= "undefined")
    document.body.style.cursor = "default";
    var dataSrc = "top.";
    if( dataFrame !== undefined && dataFrame !== null && dataFrame !== '' ) {
      dataSrc = dataSrc + dataFrame +".jspRe" + "sult.inn" + "erHTML";
    }
    else {
        dataSrc = "parent.oceanData.jspRe" + "sult.inn" + "erHTML";
    }
    return eval(dataSrc);
}

// Added by Sach to get actual data rather than HTML rendered one
// ex: result containing '>' symbol would be corrupted
function oceanGetResultArray(dataFrame) {
    // Change cursor to default.i.e not a egg timer(i.e not busy.)
    //// was originally just : document.body.style.cursor = "default";
    //if(typeof(document)!= "undefined" && typeof(document.body)!= "undefined" && typeof(document.body.style)!= "undefined")
    document.body.style.cursor = "default";
    var dataSrc = "top.";
    if( dataFrame !== undefined && dataFrame !== null && dataFrame !== '' ) {
      dataSrc = dataSrc + dataFrame +".jspResult";
    }
    else {
        dataSrc = "parent.oceanData.jspResult";
    }

    var res = eval(dataSrc);
    //The array is got by reference. Hence we do a manual copy of the array to this new Array.
    var myArr = [];
    for(var i=0;i<res.length;i=i+1) {
        var row = new Array(res[i].length);
        for(var j=0;j<res[i].length;j=j+1) {
            row[j] = res[i][j];
        }
        myArr[myArr.length] = row;
    }

    return myArr;
}

var oceanWindowCloseInUse=false;
var oceanWindowOpened = "";
// PUBLIC
// Given a string which holds the window name, this method will wait until
// the window is closed
function waitForWindowClose( windowName,  callback ) {

    // quit if one timer already setup
    if ( oceanWindowCloseInUse === true ) {
        return;
    }

    oceanWindowCloseInUse = true;
    oceanWindowOpened = windowName;

    // setup timer
    oceanWaitWinId = setInterval( "waitForWindowCloseProcess(\""+windowName+"\",\""+callback+"\")", 350 );

}

// PUBLIC
// Method that waits for a named window to close
// and then calls the given callback method
function oceanWaitForWindowClose(windowName,callback) {
    waitForWindowClose(windowName,callback);
}




// PRIVATE
// Checks to see if window is already closed
// executes the callback if so
function waitForWindowCloseProcess( windowName, callback ) {

    if ( oceanIsWindowClosed(windowName) === false ) {

        return;

    }

    // Release semaphore
    oceanWindowCloseInUse = false;

    // gc this interval object
    clearInterval( oceanWaitWinId );

    // execute the callback
    eval( callback );

    // See if testing infrastructure needs bvoting
    if ( window.oceanContinueRunning ) {

        oceanContinueRunning();

    }

}


//
// PUBLIC
//
// Tries to convert a string that represents a date
// into a JavaScript Date object.
//
// Returns -1 if it cannot.
//
// As of now, it can understand SQL dates such as :
// 2008-06-26 12:50:47.480
function oceanStringToDate( dateStr ) {
    var monthNames = ["January", "February", "March", "April", "May", "June",
    "July", "August", "September", "October", "November", "December"];

    // 1. First try date-parsing the string as is
    var arg = dateStr;
    var d = new Date( arg );
    if ( isNaN( d ) === false ) { return d; }

    // 2. try replacing dashes with slashes
    arg = arg.replace( /\-/gi, "/" );
    d = new Date( arg );
    if ( isNaN( d ) === false ) { return d; }

    // 3. try removing part after dot
    arg = arg.replace( /\..*/gi, "" );
    d = new Date( arg );
    if ( isNaN( d ) === false ) { return d; }

    // 4. try to see if there is a time component - remove that
    var blankIndex = arg.indexOf( " " );
    if ( blankIndex != -1 ) {
        arg = arg.substring( 0, blankIndex );
    }
    d = new Date( arg );
    if ( isNaN( d ) === false ) {
        return d;
    }
     // Try simplifying the string as much as possible
    // 1. trim leading and trailing spaces first, if any
    dateStr = oceanTrim( dateStr );
    // 2. remove all th's, nd's and st's first, if any
    dateStr = dateStr.replace( /[u]?st/ig, "" ); // consider Augu'st'
    dateStr = dateStr.replace( /nd/ig, "" );
    dateStr = dateStr.replace( /th/ig, "" );
    // 3. replace all dashes with whitespaces
    dateStr  = dateStr.replace( /-/ig, " " );
    // 4. replace all forward slashes with whitespaces
    dateStr  = dateStr.replace( /\//ig, " " );
    // Then expand 'post-1999' years to full form i.e. YY to YYYY
    d = dateStr.split(" ");
    var firstPart = d[0];
    var lastPart = d[d.length - 1];
    if ( lastPart.length == 2 && 
        (firstPart.length < 3 || !isInteger(firstPart) ) ) {
        var yearPart = lastPart;
        var year     = parseInt(yearPart, 10);
        if ( isInteger(year.toString()) ) {
            if ( year > 50 ) {
                yearPart = "19" + yearPart;
            }
            else {
                yearPart = "20" + yearPart;
            }
            dateStr = "";
            var loopLen = d.length - 1;
            for ( var i = 0 ; i < loopLen ; i = i + 1 ) {
                dateStr = dateStr + d[i] + " ";
            }
            dateStr = dateStr + yearPart;
        }
    }
    // then try JScript's in-built mechanism first
    var result = new Date( dateStr );
    if( !isNaN( result ) ) {
        return result;
    }
    // else see if all digits
    d = dateStr.replace(/ /gi, "");
    d = d.match(/\D/gi);
    if ( d === null ) {
        d = dateStr.split(" ");
        var monthIndex = parseInt(d[1], 10) - 1;
        dateStr = d[0] + " " + monthNames[monthIndex] + " " + d[2];
        result = new Date( dateStr );
        if ( !isNaN( result ) ) {
            return result;
        }
    }
    // else try placing a '01' date number, in case it's in "MMM YYYY" format
    d = dateStr.split(" ");
    if ( d.length <= 2 ) {
        d     = "1 " + d[ 0 ] + " " + d[ 1 ];
        result = new Date( d );
        if ( !isNaN( result ) ) {
            return result;
        }
    }
    // else try appending a 'YYYY' (current year), in case it's in "dd mmm" format
    d = dateStr.split(" ");
    if ( d.length <= 2 ) {
        var currYear = new Date().getFullYear().toString();
        d     = d[ 0 ] + " " + d[ 1 ] + " " + currYear;
        result = new Date( d );
        if ( !isNaN( result ) ) {
            return result;
        }
    }
    return -1;
}


// PUBLIC
// Formats dates as generated by the DateSelector into a format specified.
//
// Supports following
//
// %YYYY = 2001
// %Y = 2001
// %YY = 01
// %M = 01....12
// %D = 01.....31
// %mm= January, February....
// %m = Jan,Feb,Mar......
// %ww= Sunday, Monday....
// %w = Sun,Mon,Tue......
// %HH = 13,21,5,6...... ( military )
// %hh = 1,9,5,6......
// %MM = 1,9,5,6......
// %ss = 1,9,5,6......
// %0H = 13,21,05,06...... ( military, with zero-padding )
// %0h = 01,09,05,06...... ( zero padding )
// %0M = 01,09,05,06...... ( zero padding )
// %0s = 01,09,05,06...... ( zero padding )
// %ampm = am or pm
// %AMPM = AM or PM
function oceanFormatDate (dateString,format) {

    var monthArray   = [ 'January', 'February', 'March', 'April', 'May', 'June','July', 'August', 'September', 'October', 'November', 'December' ];
    var weekArray    = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ]; 
    var date = oceanStringToDate( dateString );

    // Calculate 4 digit Year
    var year = date.getFullYear();
    var yearTwoDigits = year.toString().substring(2);

    // Calculate 2 digit month
    var monthNo = date.getMonth() + 1;
    if (monthNo <10) { monthNo = "0"+monthNo;}

    // Calculate 2 digit day number
    var dayNo = date.getDate();
    if (dayNo <10) {dayNo = "0"+dayNo; }

    // Extract 3 letter month name and full name
    var monthNameFull = monthArray[date.getMonth()];
    var monthName     = monthNameFull.substring(0,3);

    // Extract 3 letter week day name and full week dayname
    var weekDayFull = weekArray[date.getDay()];
    var weekDay     = weekDayFull.substring(0,3);

    // TIME PLACEHOLDERS

    // hours and ampm
    var ampm = "am";
    var AMPM = "AM";
    var hoursMilitary = date.getHours();
    var hours = hoursMilitary;
    if ( hours > 11 ) {

        ampm = "pm";
        AMPM = "PM";

        if ( hours > 12 ) {

            hours = hours - 12;

        }

    }
    hours = hours + "";
    hoursMilitary = hoursMilitary + "";
    var zeroHours = hours.length < 2 ? "0" + hours : hours;
    var zeroHoursMilitary = hoursMilitary.length < 2 ? "0" + hoursMilitary : hoursMilitary;
    

    // minutes
    var minutes = date.getMinutes() + "";
    var zeroMinutes = minutes.length < 2 ? "0" + minutes : minutes;


    // seconds
    var seconds = date.getSeconds() + "";
    var zeroSeconds = seconds.length < 2 ? "0" + seconds : seconds;


    // Replace in users format
    format = format.replace( /%HH/g, hoursMilitary );
    format = format.replace( /%hh/g, hours );
    format = format.replace( /%MM/g, minutes ); // NOTE : this replace MUST occur before the %M replace below
    format = format.replace( /%ss/g, seconds );
    format = format.replace( /%0H/g, zeroHoursMilitary );
    format = format.replace( /%0h/g, zeroHours );
    format = format.replace( /%0M/g, zeroMinutes );
    format = format.replace( /%0s/g, zeroSeconds );
    format = format.replace( /%ampm/g, ampm );
    format = format.replace( /%AMPM/g, AMPM );

    format = format.replace( /%mm/g, monthNameFull);
    format = format.replace( /%YYYY/g, year);
    format = format.replace( /%YY/g, yearTwoDigits);
    format = format.replace( /%Y/g, year);
    format = format.replace( /%M/g, monthNo);
    format = format.replace( /%D/g, dayNo);
    format = format.replace( /%m/g, monthName);
    format = format.replace( /%ww/g, weekDayFull);
    format = format.replace( /%w/g, weekDay);

    return format;

}




// Given an array such [2,45,'suresh']
// This method writes out the array to a string in a form which can
// be passed as an argument to another web page.
function oceanArrayToString(arr) {

    var res="[";
    for (var i=0;i<arr.length;i=i+1) {
        val = arr[i];
        res = res + "'" + val + "',";
    }
    res = res.substring(0,res.length-1);
    res = res + "]";
    return res;
}

// Right_trim characters from a string
function oceanRightTrim(line,sep) {
    var len = line.length;

    while (1!=2) {
        if (line.charAt(line.length-1)==sep) {
            line = line.substring(0,line.length-1);
        } else {
           return line;
        }
    }

    return line;
}

// Left_trim characters from a string
function oceanLeftTrim(line,sep) {
    var len = line.length;

    while (1!=2) {
        if (line.charAt(0)==sep) {
            line = line.substring(1);
        } else {
           return line;
        }
    }
    return line;
}

// Allows puncation etc to be put into sql
// DEPRECATED
// Use oceanEscape() with proper parameters instead
function oceanSqlEscape(origValue) {

    // Supports  carriage return, singleQuote, doubleQuote, dollorSign
    // Basic escape from javascript
    var val = origValue;

    // Protect against a % sign (for posting) more than sql
    var re = /%/g;
    val = val.replace(re,'%');

    // Protect against single quote
    re = /'/g;
    val = val.replace(re,'"');

    // Protect against ampersand
    re = /&/g;
    val = val.replace(re,'%26');

    // Protect against a > sign
    re = />/g;
    val = val.replace(re,'%3E');

    // Protect against a > sign
    re = /\+/g;
    val = val.replace(re,'%2B');

    // Protect against bullet point and doubleQuote from microsoft word
    for (i=0;i<val.length;i=i+1) {

        if (val.charCodeAt(i)==61623) {
            val = val.substring(0,i)+"-"+val.substring(i+1);
        } else

        // Double Quote open and close
        if (val.charCodeAt(i)==8220 || val.charCodeAt(i)==8221) {
            val = val.substring(0,i)+'"'+val.substring(i+1);
        }

        if (val.charCodeAt(i)==8211) {
            val = val.substring(0,i)+'-'+val.substring(i+1);
        }

        // single apostrophe
        if (val.charCodeAt(i)==8217) {
            val = val.substring(0,i) + "'" + val.substring(i+1);
        }

        // three dots
        if (val.charCodeAt(i)==8230) {
            val = val.substring(0,i) + "..." + val.substring(i+1);
        }
    }

    return escape(val);

/*
    val = oceanEscape("sqlField", val);
    val = msWordEscape(val);
    val = oceanEscape("oceanExec", val);

    return val;
*/

}


//Keeps a count of number of tabs, Basically used to make the first tab active
var tabcount=0;
var oldId="";
var oldColour = "";

// PUBLIC
// Dynamically change the text displayed by a textual OceanTab widget
function oceanTab_changeText( id, newText ) {

    // get reference to span
    var tabRef = oceanGetElementById( "tabText" + id );

    // see if currently bolded
    var currText = tabRef.innerHTML.toLowerCase();
    if ( currText.indexOf( "<b>" ) != -1 
        && newText.toLowerCase().indexOf( "<b>" ) == -1 ) {
        newText = "<B>" + newText + "</B>";
    }
    tabRef.innerHTML = newText;

}


// reverse the highlight colour of an oceanTab
function oceanReverse( id, clr ) {

    var colour = "";
    if( clr !== undefined && clr !== null && clr !== ''){
        colour = clr;
    }

    var tdRef = oceanGetElementById( "tabText" + id );

    //Swap the color if the text
    var temp = tdRef.style.color;
    tdRef.style.color = tdRef.className;
    tdRef.className = temp;

    var line = tdRef.innerHTML;
    if ( colour == 'textOnly' ) {
        if (line.indexOf("<B>")>=0) {
            line = line.substring(3);
        }
        else {
            line = "<B>"+line;
        }
        tdRef.innerHTML = line;
        
        return;
    }
    

   var stripe = "/sys" + "tem/tab/stripe_"+colour+".gif";
   var myidL = oceanGetElementById( "tableft"+id );
   var myidM = oceanGetElementById( "tabmiddle"+id );
   var myidR = oceanGetElementById( "tabright"+id );

   var wt = tdRef.style.fontWeight;
   //if (line.indexOf("<B>")>=0 || line.indexOf( "<b>" ) >= 0 ) {
   if ( wt == 'bold' ) {
      wt = "normal";
      line = line.substring(3);
      myidL.src="/sys" + "tem/tab/left_"+colour+".gif";
      myidM.style.backgroundImage= "url(/sys" + "tem/tab/middle_"+colour+".gif)";
      myidR.src="/sys" + "tem/tab/right_"+colour+".gif";

   } else {
      line = "<B>"+line;
      wt = "bold";
      myidL.src="/sys" + "tem/tab/left_stripe_"+colour+".gif";
      myidM.style.backgroundImage="url(/sys" + "tem/tab/middle_stripe_"+colour+".gif)";
      myidR.src="/sys" + "tem/tab/right_stripe_"+colour+".gif";
   }
    //tdRef.innerHTML = line;
    tdRef.style.fontWeight = wt;
}


// make a tab
// - This function provides the option to different color for active and deactive images.
function oceanTabColoured( id, text , code, colour, deactiveTextColour, 
                            activeTextColour, fontFamily, fontSize ) {
    
    if ( fontFamily === undefined || fontFamily === null ) {
        fontFamily = "verdana";
    }
    if ( fontSize === undefined || fontSize === null ) {
        fontSize = "11";
    }
    fontFamily = oceanTrim( fontFamily );
    fontSize   = oceanTrim( fontSize );

    tabcount = tabcount + 1;

    if (text.indexOf("<B>")>=0) {
      text = text.substring(3);
    }
    
    code=  "oceanTabPress('"+id+ "','" + code + "','" + colour + "'";
    
    if ( colour == 'textOnly' ) {

    var mycmd = '<i style="cursor:pointer;">' +
                '<TABLE cellpadding=3 style="height:100%;width:100%"><TR>' +
                ' <TD NOWRAP ALIGN=CENTER onclick="'+  code +',event)" style="vertical-align:middle;width:100%;border:1px solid gray;">'+
                " <span id=\"tabText" + id + "\" style=\"color:" + deactiveTextColour;
                if ( fontFamily !== '' ) {
                    mycmd = mycmd + ";font-family:" + fontFamily;
                }
                if ( fontSize !== '' ) {
                    mycmd = mycmd + ";font-size:" + fontSize;
                }
                mycmd = mycmd + "\" class=\"" + activeTextColour + '">'+text+
                ' </span></TD>'+

                '  </TR></TABLE>'+
                '</i>';
                
    }
    else {
    
    var left = "/sys" + "tem/tab/left_"+colour+".gif";
    var middle = "/sys" + "tem/tab/middle_"+colour+".gif";
    var right = "/sys" + "tem/tab/right_"+colour+".gif";

    mycmd = '<span style="cursor:pointer;">' +
                '<TABLE CELLPADDING=0 CELLSPACING=0><TR>' +

                ' <TD NOWRAP onclick="'+  code +',event)">'+
                ' <IMG id="tableft'+id+'" SRC=' + left + ' align=absbottom>' +

                ' <TD NOWRAP onclick="'+ code +',event)" style="vertical-align:middle;background-image:url('+
                  middle +');background-repeat:repeat-x;" id="tabmiddle'+id+'">'+
                " <span id=\"tabText" + id + "\" style=\"height:100%;color:" + deactiveTextColour;
                if ( fontFamily !== '' ) {
                    mycmd = mycmd + ";font-family:" + fontFamily;
                }
                if ( fontSize !== '' ) {
                    mycmd = mycmd + ";font-size:" + fontSize;
                }
                mycmd = mycmd + ";\" class=\"" + activeTextColour + '">'+text+
                ' </span></TD>'+

                ' <TD NOWRAP onclick="'+ code +',event)" style="vertical-align:top;">'+
                ' <IMG id="tabright'+id+'" SRC='+ right +
                '  align=absbottom></TD></TR></TABLE>'+
                '</span>';
    
    }

    var myIdRef = oceanGetElementById( id );
    myIdRef.innerHTML = mycmd;

// we need to do the remainder in a separate thread
// because in other browsers like FF, the rendering 
// of the above innerHTML = takes time
    var cmd = "oceanTabColoured2( " + tabcount + ",'" + id + "','" + colour + "')";
    setTimeout( cmd, 1 );

}

//--------------------------------------------------------
//If we have a fixed image for the tab, we can call this function
//Need to pass active and deactive images. 
//id is the HTML TD or span ID
function oceanImageTab(id, deactiveImg, activeImg, code) {

    tabcount=tabcount+1;
    
    code=  "oceanImgTabPress('tab"+id+ "','" + code + "','" + deactiveImg + "','" +  activeImg + "'";
    
    var thisImg = deactiveImg;
    var othrImg = activeImg;
    if(tabcount==1) {
        
        thisImg = activeImg;
        othrImg = deactiveImg;
        oldId = "tab"+id;
    }
    
    var mycmd = '<IMG id="tab'+id+'" VALIGN=TOP WIDTH=100% onclick="'+  code +',event)" ' +
                'SRC="' + thisImg + '" NAME="' + othrImg + '" style="cursor:pointer;">';
                
    eval ("document.all."+id+".innerHTML=mycmd");
}


// make a tab 
// - This function provides the option to specify active/deactive images.
function oceanTab(id, text , code, colour, deactiveImg, activeImg) {

    if ( deactiveImg !== undefined && deactiveImg !== null && deactiveImg !== "" 
        && activeImg !== undefined && activeImg !== null && activeImg !== "" ) {
        
        oceanImageTab(id, deactiveImg, activeImg, code);
        return;
    }
    
    oceanTabColoured(id, text , code, colour, "black", "black"); //The default is black
}


// carry over from above.
function oceanTabColoured2( tabcount, id, colour ) {

    // highlight the first tab
    if ( tabcount == 1 ) {
        oceanReverse( id, colour ) ;
        oldId = id;
        oldColour = colour;
    }

}


// handler method on click of any of oceanTabs
function oceanTabPress (id,code,colour) {

    oceanReverse(id, colour);
    oceanReverse(oldId,oldColour);
    oldId=id;
    oldColour = colour;
    eval(code);

}




// Handles o nclick when we have image tabs
function oceanImgTabPress(id, code, deactiveImg, activeImg) {

    var x = eval(oldId + ".src");
    eval(oldId + ".src = "+ oldId +".name");
    eval(oldId + ".name = '"+ x +"'");
    x = eval(id + ".src");
    eval(id    + ".src = "+ id    +".name");
    eval(id + ".name = '"+ x +"'");
    oldId=id;
    eval(code);
}

// get the full path of window's current location
function oceanFullPath(x) {
    var fullpath = window.location.pathname;
    fullpath = fullpath.substring(0,fullpath.lastIndexOf('/')+1);
    return fullpath+x;
}

// -------- ESCAPE METHODS -------- //


// This is more of a hack code
// since, for some reason, the
// built-in escape doesn't escape
// the plus (+) character
function singleEscape(arg) {

    arg = escape(arg);
    arg = arg.replace(/\+/g,"%2B");
    return arg;

}

// JSP's called by oceanExec's
// need to be escaped twice
function oceanExecEscape(arg) {

    // we escape twice since oceanExec
    // uses the generic JSP executor

    arg = singleEscape(arg);
    arg = singleEscape(arg);
    return arg;

}




// MSSQLESCAPEing for INSERTs / UPDATEs / ='s
function sqlEscape(origValue) {

    var val = origValue;
    val = val.replace(/'/g,"''");
    return val;

}

// MSSQLESCAPEing for LIKE's
function sqlEscapeLike(origValue) {

    var val = origValue;

    var re = /\[/g;
    val = val.replace(re,'[[]');

    re = /%/g;
    val = val.replace(re,'[%]');

    re = /_/g;
    val = val.replace(re,'[_]');

    val = sqlEscape(val);

    return val;
}

// Some MSWORD characters have to be specially escaped
function msWordEscape( arg ) {

    for ( var i = 0 ; i < arg.length ; i = i + 1 ) {

        var nextChar = arg.charCodeAt( i );

        // Protect against bullet point and doubleQuote from microsoft word
        if ( nextChar == 61623 ) {

            arg = arg.substring( 0 , i ) + "-" + arg.substring( i + 1 );

        } else

        // Double Quote open and close
        if ( nextChar == 8220 || nextChar == 8221 ) {

            arg = arg.substring( 0 , i ) + '"' + arg.substring( i + 1 );

        } else 

        if ( nextChar == 8211 ) {

            arg = arg.substring( 0 , i ) + '-' + arg.substring( i + 1 );

        } else 

        if ( nextChar == 8216 ) {

            arg = arg.substring( 0 , i ) + "`" + arg.substring( i + 1 );

        } else

        if ( nextChar == 8217 ) {

            arg = arg.substring( 0 , i ) + "'" + arg.substring( i + 1 );

        } else

        if ( nextChar == 8230 ) {

            arg = arg.substring( 0 , i ) + "..." + arg.substring( i + 1 );

        } else

        if ( nextChar == 61664 ) {

            arg = arg.substring( 0 , i ) + "->" + arg.substring( i + 1 );

        } else

        if ( nextChar == 8226 ) {

            arg = arg.substring( 0 , i ) + String.fromCharCode( 176 ) + arg.substring( i + 1 ); // °

        }

    }

    return arg;

}

// PUBLIC
// Well-known escape sequences
// Specify proper type of escape as first argument
// followed by the actual string to escape
function oceanEscape(type, arg) {

    if (type=="sqlField") {
        return sqlEscape(arg);
    }

    else if (type=="sqlLikeField") {
        return sqlEscapeLike(arg);
    }

    else if (type=="url") {
        return singleEscape(arg);
    }

    else if (type=="oceanExec") {
        return oceanExecEscape(arg);
    }

    else if(type=="msWord") {
        return msWordEscape(arg);
    }

    return sqlEscape(type);
}


// PUBLIC
// Use this method to open windows henceforth
function oceanOpen( url, height, width, name, scrollbars ) {

    var halfScreenWidth  = screen.width / 2;
    var halfScreenHeight = screen.height / 2;

    if ( height === undefined || height === null ) {

        height = halfScreenHeight;

    }
    if ( width === undefined || width === null ) {

        width = halfScreenWidth;

    }
    if ( name === undefined || name === null ) {

        name = "";

    }

    width   = parseInt(width,10);
    height  = parseInt(height,10);


    var midx = halfScreenWidth - width / 2;
    var midy = halfScreenHeight - height / 2;

    var openOptions = "RESIZABLE=1,STATUS=NO,ADDRESS=NO,TOOLBAR=NO,HEIGHT=" + height + ",WIDTH=" + width + ",LEFT=" + midx + ",TOP=" + midy;
    if ( scrollbars !== undefined && scrollbars !== null ) {
        openOptions = openOptions + ",SCROLLBARS=YES";
    }

    win = open( url, name, openOptions + ",STATUS=1" );

    return win;

}

//
// PUBLIC
// Method to pop up a file selector widget for given file path
function widgetFileSelector_open(path,edit) {
    if (path.indexOf("/")<0) { path  = path +"/"; }

    return showModalDialog("/sys" + "tem/fileSelector/selectFile.html.nocache?path="+
                           path+
                           "&edit="+edit+"&width=375&height=405",
                           "",
                           "dialogHeight:32;dialogWidth:25;edge:Raised;center:Yes;help:No;resizable:No;status:yes;scroll:no");
}


var lastUniqueId=null;
// 
// Return the time in milliseocnds as a unique id
function oceanUniqueId () {
    var tmp = new Date().getTime();
    if (tmp == lastUniqueId) {
       return oceanUniqueId();
    }
    lastUniqueId = tmp;
    return tmp;
}

// *** API
// Tells you if a variable exists returns boolean
function oceanNoSuchVariable(name) {
   return eval("!window."+name);
}



lastObj=null;
privateLog = "";
oceannext=null;
//
// returns object properties on screen useful for debugging.
function oceanShowBrowser(obj) {

  if( obj === undefined || obj === null) { return ""; }

  if (!obj.zzzzzz_OCEAN_BACK_TO_LAST_OBJECT) {
     obj.zzzzzz_OCEAN_BACK_TO_LAST_OBJECT = lastObj;
  }

  lastObj=obj;
  var res= "<HTML><TABLE>";

  res = res + "<TR><TD o" + "nClick='top.opener.oceannext=\"zzzzzz_OCEAN_BACK_TO_LAST_OBJECT\"; top.close()'>";
  res = res + "<u>BACK UP TO PARENT</u><TD>";

  try {

    var temp = [];
    var loopLen = obj.length;
    var i = 0;
    for( ; i < loopLen ; i = i + 1 ) {
        var nextName = obj[ i ];
        temp[temp.length] = nextName;
    }

    temp = temp.sort();

    for(i=0;i<temp.length;i=i+1) {
         name = temp[i];
         var onc="";
         var val = obj[name];
         if (""+obj[name]=="[object]") {
             onc=" o" + "nClick='top.opener.oceannext=\"" + name +"\"; top.close()'";
             val = "<u>" + val + "</u>";
         }

         res = res + "<TR><TD>" + name + "<TD "+ onc +">" + val ;
    }
  } catch(exception) {
  }

  res = res + "</TABLE>";

  objbwin=window.open('',"objbwin",'height=500,width=650,scrollbars=1,status=1');
  var tmp = objbwin.document;
  tmp.write(res);
  oceanWaitForWindowClose("objbwin","privateNextObject()");

  //  tmp.close();
}

// INTERNAL
function privateNextObject() {
    if (!oceannext) {return;}
    if (oceannext === null) {return;}
    oceanShowBrowser(lastObj[oceannext]);
    oceannext=null;
}

// -----------------------------------
// Generates a PDF file that is equivalent
// to the currently displayed HTML page
//
// the 'params' param is optional
// currently supported param is :
//
// "&noPageNumbers=true" - turns off page numbering in the generated PDF
// callback - if set then will callback your function with the filename of the pdf file that has been generated
// -----------------------------------
function oceanHtmlToPdf(params,callback) {
    // if this function is called in succession, we need to reset these forms vars
    // else the convert won't work
    var formRef = document.forms.meform1;
    formRef.jspCmd.value   = '';
    formRef.jspArgs.value  = '';
    formRef.callBack.value = '';
    formRef.oceanUrlForward.value = '';

    var htmlsource = document.body.innerHTML;
        htmlsource = oceanEscape("oceanExec", htmlsource);
        htmlsource = htmlsource.replace(/\\*>/gi,"\\>");

    var filename = "suresh.html";
    if ( params === undefined || params === null ) {
        params = "";
    }

    if ( params.indexOf("&") !== 0 && params !== '' ) {
        params = "&" + params;
    }

    if (!callback) {

       // generate pdf and open it in a new wiudow
       oceanExecLong("pdf.make()",
                  "htmlcontentMaxSubstitute=-1&htmlcontent="+htmlsource+
                  "&filepath="+filename + params,"private_pdfDone");
    } else {

       // generate pdf and return the filename to the user
       oceanExecLong("pdf.make()",
                  "htmlcontentMaxSubstitute=-1&htmlcontent="+htmlsource+
                  "&filepath="+filename + params,callback);

    }
}



// --- Returns the apps current working directory
function oceanAppDirectory( relative ) {

    var res = "" + top.location;
    res = res.substring(0,res.lastIndexOf("/") + 1);
    if ( relative !== undefined && relative !== null ) {
        var startOfClient = res.toLowerCase().indexOf("/client/");
        if ( startOfClient != -1 ) {
            res = res.substring( startOfClient );
        }
    }

    return res;
}

// --- when the pdf has been created, this function opens the pdf file
function private_pdfDone(res) {
    var path = "/OpenUploadedFile_/temp/" + res;
    open( path, "", "status=1" );
}


/*********************************** CROSS BROWSER SECTION - START *************************************/
// Methods herein were created specifically so that developers who use these functions
// will have their apps cross-browser compatible - i.e. will be able to run their apps
// on any of the four well-known browsers viz. : IE, Netscape, Firefox, Opera


 
// PUBLIC
// use this method to dynamically add an event handler
// to a given event type
// Ex. :
// oceanAttachEvent("onbeforeunload", "myHandler(arg1, arg2)", document.body );
// oceanAttachEvent("onbeforeunload", "myHandler(arg1, arg2)", oceanGetElementById(test), false );
// the last 2 parameters 'obj' and 'useCapture' parameter are optional.
// If the third 'object' parameter is not provided, the 'window' object is assumed
function oceanAttachEvent(evnt, func, obj, useCapture ) {
 
    if ( useCapture === undefined || useCapture === null ) {
 
        // This is Since at Default we set bubble 
        // of event to false. Assumed from Mozilla.
        useCapture = false;
 
    }
 
    if ( obj === undefined || obj === null ) {
 
        //Assign the Window Object if no object is used.
        obj = window;   
     
    }
 
    // Create a New method handler stating the cancelBubble parameter
    var newHandler = null;
    if ( typeof(func) == 'function' ) {
 
        // Create New Anonymous Function
        newHandler = function( evt ) {
            func(evt);
            evt.cancelBubble = useCapture;
        };
        
 
    } else {
 
        // Create New Anonymous Function
        newHandler = function( evt ) {
            eval(func);
            evt.cancelBubble = useCapture;
        };
 
    }


    // handle Event cases
    var onStripRule =  /^on/i;
    evnt = evnt.toLowerCase();
    evnt = evnt.replace(onStripRule, "");
      
    // Retain reference to this new method
    
    var evntFunc = evnt + func;
    obj[ evntFunc ] = newHandler;

 
    // IE
    if ( document.attachEvent ) {
 
        // AttachEvent for IE browser
        obj.attachEvent( "on" + evnt, newHandler );
 
    } else {
    // NON-IE
 
        // AddEventListener for Other Browsers.
        obj.addEventListener( evnt, newHandler , false);
 
    }
 
}



// PUBLIC
// use this method to dynamically remove an event handler
// from a given event type
// Ex. :
// oceanDetachEvent( document.body, "onbeforeunload", "myHandler(arg1, arg2)" );
function oceanDetachEvent(evnt, func, obj ) {
 
    if ( obj === undefined || obj === null ) {
 
        //Assign the Window Object if no object is used.
        obj = window;      
  
    }
      
    // Handle Event cases
    var onStripRule =  /^on/i;
    evnt = evnt.toLowerCase();
    evnt = evnt.replace(onStripRule, "");   

    var methodRef = obj[ evnt + func ];
    if( document.detachEvent ) {
 
        // IE browser
        obj.detachEvent( "on" + evnt, methodRef );
 
    } else {
 
        // OTHER browsers
        obj.removeEventListener( evnt, methodRef, false );
 
    }
 
}

/*********************************** CROSS BROWSER SECTION - END *************************************/




/*********************************** AUTO-CLOSE CHILD WINDOWS SECTION - START *************************************/

var oceanChildWindows = [];
var oceanChildWindowsParent = null;

// PRIVATE
// Auto-closes child windows
// user can set a 'oceanAutoClose' global var to 
// 'false' if need to override auto-close
function private_oceanCloseChildWindows() {

    // see if auto-close should be overridden
    // user sets the 'oceanAutoClose' global var to 'false' if so
    var autoCloseRef = true;
    if ( typeof( oceanAutoClose ) == 'boolean' ) {

        autoCloseRef = oceanAutoClose;

    } else if ( oceanChildWindowsParent !== null ) {

        if ( typeof( oceanChildWindowsParent.oceanAutoClose ) == 'boolean' ) {

            autoCloseRef = oceanChildWindowsParent.oceanAutoClose;

        }

    }

    if ( autoCloseRef === false ) {
        return true;
    }

    if ( typeof( oceanChildWindows ) != 'object' ) {
        return true;
    }

    var loopLen = oceanChildWindows.length;
    for ( var i = 0 ; i < loopLen ; i = i + 1 ) {

        var nextChildWindow = oceanChildWindows[ i ];

        try {
            nextChildWindow.close();
        }
        catch( e ) {
        }

    }

    return true;

}



// PRIVATE
// Register a given window as child to this window
function private_oceanRegisterChildWindow( winRef ) {

    oceanChildWindows[ oceanChildWindows.length ] = winRef;

}

// PRIVATE
// Method that sets up the system that auto-closes child windows
function private_oceanCloseChildWindowsSetup() {

    var methodRef = null;
    var winRef = null;
    try {
        winRef = top.opener.top;
        methodRef = winRef.private_oceanRegisterChildWindow;
        var objType = typeof( methodRef );
        if ( objType != 'function' && objType != 'object' ) {
            winRef = top.opener.top.frames[ 0 ];
            methodRef = winRef.private_oceanRegisterChildWindow;
        }
    }
    catch( e ) {
    }

    if ( methodRef !== null ) {

        methodRef( window.top );
        oceanChildWindowsParent = winRef;

    }

    oceanAttachEvent( "onbeforeunload", private_oceanCloseChildWindows );

}

oceanAttachEvent( "onload", private_oceanCloseChildWindowsSetup );

/*********************************** AUTO-CLOSE CHILD WINDOWS SECTION - END *************************************/

// PRIVATE
// Internal function that disables the right-click
function private_oceanDisableRightClick( evt ) {

    evt.returnValue = false;

}


// PUBLIC
// Call this method to prevent right-clicks on a page
function oceanDisableRightClick() {

    oceanAttachEvent( "oncontextmenu", private_oceanDisableRightClick, document.body, true );

}





// PUBLIC
// Read a file from client's hard drive
function oceanReadFile( filename ) {

    var fs, a, ForAppending;

    ForAppending = 8;

    var ForReading = 1, ForWriting = 2;

    try {
        fs = new ActiveXObject("Scripting.FileSystemObject");
    } catch(x) {

        var site = ""+document.location;
        site = site.substring(0,site.indexOf("client"));
        alert("Your internet explorer settings are not allowing this facility to run. \n\n" + 
              "This can be fixed in 2 easy steps.\n\n"+
               " 1.  In internet explorer click on menu option tools -> internet options - > security tab -> select trusted sites, " + 
               "\n      then click on the 'sites' button and add\n      "+ site+ " to your trusted sites list\n\n" +
               " 2. In internet explorer click on menu option tools -> internet options - > security tab -> select trusted sites, " + 
               "\n     then click on the button 'Custom level', then scroll through the list of options and find\n" +
               "     'Initialise and script Active X controls not marked as safe for scripting', ensure its option\n" + 
               "     is set to 'Enabled'\n"  );
        return;
    }

    a = fs.OpenTextFile(filename, ForReading, false);

    var content = a.ReadAll();
    a.Close();
    return content;
}


// PUBLIC
// Use this method to display a red
// gmail-like status on top-right corner 
// of page for 2 seconds
// Provide a message of 'Done' to hide the status message
// The second parameter is optional to auto-hide 
// the message in X milliseconds
function oceanStatus( statusString, optionalTime ) {

    var divRef = oceanGetElementById( "oceanStatusWidgetDiv" );

    // define a div if not already done so
    if ( divRef === null ) {
        var cssText = "position:absolute;top:0px;background:#CC4444;color:white;z-index:20;padding:3px;font-size:12px;font-family:sans-serif;";
        oceanStatusDivElement = document.createElement("DIV");
        oceanStatusDivElement.style.cssText= cssText;
        oceanStatusDivElement.noWrap = true;
        oceanStatusDivElement.id = "oceanStatusWidgetDiv";
        document.body.appendChild( oceanStatusDivElement );
        
        divRef = oceanGetElementById( "oceanStatusWidgetDiv" );
    }

    // see if user wants to just hide the status message
    if ( statusString == 'Done' ) {
        divRef.style.visibility = 'hidden';
        return;
    }

    // set the message text to what the user provided
    divRef.innerHTML = statusString;        
    var left = document.body.clientWidth - divRef.offsetWidth;

    divRef.style.left =  left + "px";
    divRef.style.visibility = 'visible';
    
    if ( optionalTime === undefined || optionalTime === null ) {
        optionalTime = -1;
    }

    // auto-hide it or show forever
    if ( optionalTime != -1 ) {
        setTimeout("oceanGetElementById( 'oceanStatusWidgetDiv' ).style.visibility = 'hidden';", optionalTime );
    }

}


// PUBLIC
// Use this method to get the set of DOM rules / cssRules
// for the next 'styleSheet' object in the document.styleSheets collection.
function oceanGetStyleSheetObjectRules( arg ) {

    // IE is 'rules'
    if ( ocean_browser == 'ie' ) {

        return arg.rules;

    }

    // Gecko is 'cssRules'
    return arg.cssRules;

}



// PUBLIC
// use this method to the a list of 
// all included scripts in a file
// returns an array of DOM Script objects
function oceanGetIncludedScripts() {

    // get a collection of all scripts, included or embedded
    var allScripts = document.getElementsByTagName("SCRIPT");
    
    // setup our empty result
    var res = [];

    var loopLen = allScripts.length;
    for( var i = 0; i < loopLen ; i = i + 1 ) {
    
        var nextScript = allScripts[ i ];
        if ( nextScript.src === '' ) {

            continue;

        }

        // get only those that have been included
        res.push( nextScript );

    }
    
    return res;
    
}


//
// Traps all js errors
function oceanJSErrorCatch(a,b,c,d) {
    //var lines= document.body.innerHTML.split('\n');
    //var errorline = lines[c];
    
    var dev_servers = "";
    if (dev_servers.indexOf(document.domain)>=0) {
        oceanShowBrowser(document);
    }

    var loop;
    var paths="";
    var scriptsColl = oceanGetIncludedScripts();
    var loopLen = scriptsColl.length;
    for ( loop = 0 ; loop < loopLen ; loop = loop + 1 ) {

       paths = paths + "<BR>" + scriptsColl[ loop ].src;

    }
    b = paths + b;

    // Get error line
    var source = document.body.innerHTML;
    source = source.split("\n");

    var bugline = ((c-1) + ":" + source[c-1]   + "\n" +
                   (c)   + ":" + source[c]     + "\n" +
                   (c+1) + ":" + source[c+1]   + "\n"
                  );

    //alert(bugline);
    var bug = "<B>JS Error:</B> "     + a +
              "<BR><BR><B>Error is in one of following files:</B> "  + b +
              "<BR><BR><B>On Line:</B> " + c;
                // the following statement only works on IE 
                // since the event object is globally available
                if ( ocean_browser == 'ie' ) {
                      bug = bug + "<BR><BR><B>Character:</B> " +  eval( "eve" + "nt.errorCharacter" ) +
                      "<BR><BR><B>Error Type:</B> "   + eval( "ev" + "ent.errorCode" );
                }
  bug = bug + "<BR><BR><B>Window Title:</B> " + document.title +
              "<BR><BR><B>Last OceanExecLong log </B>" + privateLog + "<BR><BR><BR>";


    file = window.location.pathname;
    file = file.substring (file.lastIndexOf("/"));

    var subject = oceanEscape("url","JS error on " + window.location.host + " : " + file);

    // Send email if a live server
    if (dev_servers.indexOf(document.domain)<0) {
        var report= new Image(1,1);
        report.src="/sys" + "tem/clientJSP/reportJsError.html.nocache?subject="+subject+"&bug="+
               oceanEscape("url",bug);
    }

    // Lets always log the message to the console
    var logmessage= new Image(1,1);
        logmessage.src="/sys" + "tem/clientJSP/logJsError.html.nocache?subject="+subject+"&bug="+
               oceanEscape("url",bug);

    // show on screen
    if (dev_servers.indexOf(document.domain)>=0) {
        var myerrorwin=window.open('',"myerrorwin"+oceanUniqueId(),                            'height=500,width=650,scrollbars=1,status=1');
      var tmp = myerrorwin.document;
      tmp.write(bug);
    }

    return false;
}
window.onerror=oceanJSErrorCatch;
