﻿// utils.js

// globals
var g_onEducationPage = false;
var WIDTH_OF_PICTURE_POEM_IN_PX = 600;
var HEIGHT_OF_PICTURE_POEM_IN_PX = 275;

// get the left or top of element e in absolute coordinates, even if it's a relatively positioned element
function absLeft(e) { return ( e.offsetParent ? e.offsetLeft + absLeft(e.offsetParent) : e.offsetLeft ); }
function absTop(e) { return ( e.offsetParent ? e.offsetTop + absTop(e.offsetParent) : e.offsetTop ); }

function $(s) { return document.getElementById( s ); }

// master page scripts
function masterPageLoadHandler()
{
    if ( window.pageLoadHandler ) pageLoadHandler();
    if ( window.initializeRatingsControls ) initializeRatingsControls();

    attachEventToElement( document, "contextmenu", suppressRightClick, true );
    
    // light up nav bar element that corresponds to the current page
    var selectedLight = document.getElementById( "divNavBar" ).getElementsByTagName( "img" )[0];
    var pageFilename = location.pathname.slice( location.pathname.lastIndexOf( "/" ) + 1 );
    var navBarElementOfCurrentPage = null;

    switch ( pageFilename )
    {
    case "compose_dragdrop.aspx":
        navBarElementOfCurrentPage = document.getElementById( "divNavBar" ).getElementsByTagName( "a" )[0];
        break;
    
    case "gallery.aspx":
        if ( location.search.indexOf( "MyPicturePoems" ) != -1 )
            navBarElementOfCurrentPage = document.getElementById( "divNavBar" ).getElementsByTagName( "a" )[2]
        else
            navBarElementOfCurrentPage = document.getElementById( "divNavBar" ).getElementsByTagName( "a" )[1];
        break;        
    
    case "about.aspx":
        navBarElementOfCurrentPage = document.getElementById( "divNavBar" ).getElementsByTagName( "a" )[4];
        break;

    case "future.aspx":
        navBarElementOfCurrentPage = document.getElementById("divNavBar").getElementsByTagName( "a" )[5];
        break;

    case "educators.aspx":
    case "learnit.aspx":
    case "rhymeit.aspx":
    case "writeit.aspx":
        navBarElementOfCurrentPage = document.getElementById( "divNavBar" ).getElementsByTagName( "a" )[3];
        g_onEducationPage = true;
        break;    
    
    default:
        if ( location.pathname.indexOf( "lessonplans" ) != -1 )
        {
            navBarElementOfCurrentPage = document.getElementById( "divNavBar" ).getElementsByTagName( "a" )[3];
            g_onEducationPage = true;
        }
        else if ( location.pathname.indexOf( "admin" ) != -1 )
        {
            navBarElementOfCurrentPage = document.getElementById( "divNavBar" ).getElementsByTagName( "a" )[6];
        }
        break;
    }
    
    if ( pageFilename == "gallery.aspx" ) // hack to fix footer layout on gallery
    {
        $("divFooter").style.marginTop = document.getElementsByTagName("tbody")[0].parentNode.offsetTop + 
            document.getElementsByTagName("tbody")[0].parentNode.offsetHeight - 
            ((navigator.userAgent.search("MSIE") != -1) ? 670 : 810) + "px";
    }
    
    if ( navBarElementOfCurrentPage != null )
    {
        var firstNavSpan = document.getElementById( "divNavBar" ).getElementsByTagName( "span" )[0];
        if ( firstNavSpan.offsetLeft > 0 )  // different browsers lay out spans and their contents differently
        {
            selectedLight.style.left = navBarElementOfCurrentPage.offsetLeft + "px"; // IE7 & similar
        } else {
            selectedLight.style.left = navBarElementOfCurrentPage.parentNode.offsetLeft + "px"; // FF2 & similar
        }
        selectedLight.style.width = navBarElementOfCurrentPage.offsetWidth + "px";
        selectedLight.style.visibility = "visible";
    }
}

function showHover( e, isEducationLink )
{
    if ( isEducationLink && g_onEducationPage )
    {
        var hoverLight = document.getElementById( "divNavBar" ).getElementsByTagName( "img" )[2];
        document.getElementById( "divNavBar" ).getElementsByTagName( "img" )[1].style.visibility = "hidden";
    }
    else
    {
        var hoverLight = document.getElementById( "divNavBar" ).getElementsByTagName( "img" )[1];
        document.getElementById( "divNavBar" ).getElementsByTagName( "img" )[2].style.visibility = "hidden";
    }
    var firstNavSpan = document.getElementById( "divNavBar" ).getElementsByTagName( "span" )[0];
    if ( firstNavSpan.offsetLeft > 0 )  // different browsers lay out spans and their contents differently
    {
        hoverLight.style.left = e.offsetLeft + "px"; // IE7 & similar
    } else {
        hoverLight.style.left = e.parentNode.offsetLeft + "px"; // FF2 & similar
    }
    
    hoverLight.style.width = e.offsetWidth + "px";
    hoverLight.style.visibility = "visible";
}

function hideHover()
{
    document.getElementById( "divNavBar" ).getElementsByTagName( "img" )[1].style.visibility = "hidden";
    document.getElementById( "divNavBar" ).getElementsByTagName( "img" )[2].style.visibility = "hidden";
}

function showHelpWindow()
{
    window.open(document.location.href.replace( "/lessonplans", "" ).replace( "/admin", "" ).replace( /[a-zA-Z0-9\-_]+\.aspx/, "help.aspx"), 
        "HelpWindow", "width=450,height=600,location,resizable,scrollbars");
}


// Remove all children from the given node; if tagOrClass is specified, remove only the children with that tag,
// or children of that class if preceded by a . (period).

function removeChildren( node, tagOrClass ){
    var childOfNode = node.firstChild;
    var nextChildOfNode = null;
    
    if ( tagOrClass )
    {
        if ( tagOrClass.substring( 0, 1 ) == "." )
        {
            tagOrClass = tagOrClass.substring( 1 );
            while( childOfNode )
            {
                nextChildOfNode = childOfNode.nextSibling;
                if( childOfNode.className == tagOrClass ) node.removeChild( childOfNode );
                childOfNode = nextChildOfNode;
            }
        }
        else
        {
            var tagUpper = tagOrClass.toUpperCase();
            var tagLower = tagOrClass.toLowerCase();
            
            while ( childOfNode )
            {
                nextChildOfNode = childOfNode.nextSibling;
                if( ( childOfNode.tagName == tagUpper ) || ( childOfNode.tagName == tagLower ) ) node.removeChild( childOfNode );
                childOfNode = nextChildOfNode;
            }
        }
    }
    else
    {
        while ( childOfNode )
        {
            nextChildOfNode = childOfNode.nextSibling;
            node.removeChild( childOfNode );
            childOfNode = nextChildOfNode;
        }
    }
}

String.prototype.toInitialCap = function() { return this.substring( 0, 1 ).toUpperCase() + this.substring( 1 ); }
String.prototype.JSONEncode = function() { return this.replace( /\"/g, "\\\"" ); }

function suppressRightClick(e)
{
    if ( !e ) e = window.event;   // Earlier IE event model
    if ( e.target ) { var rightClickedElement = e.target; /* DOM */ }
    else { var rightClickedElement = e.srcElement; /* IE */ }

    if ( rightClickedElement.getAttribute("suppress-context-menu") )
    {
        if ( rightClickedElement.getAttribute("suppress-context-menu") == "true" )
        {
            if (e.stopPropagation) e.stopPropagation()
            else return !( rightClickedElement.getAttribute("suppress-context-menu").toLowerCase() == "true" );
        }
    }
    else
    {
        return true;
    }
}


function threeDigitString(x) { return ( ("00" + x).substr(("00" + x).length - 3, 3 ) ); }

function friendlyTimeElapsed( days, hours, minutes )
{
    var friendlyTime = days + " days";
    
    if ( minutes < 5 )
    {
        friendlyTime = "a few minutes";
    }
    else if ( ( minutes < 60 ) && ( minutes > 5 ) )
    {
        friendlyTime = minutes + " minutes";
    }
    else if ( hours == 1 )
    {
        friendlyTime = "an hour";
    }
    else if ( ( hours > 1 ) && ( hours < 24 ) )
    {
        friendlyTime = hours + " hours";
    }
    else if ( days == 1 )
    {
        friendlyTime = "a day";
    }
        
    return friendlyTime;
}


// trim a string down to last full word shorter than the given trimToLength characters. if delimiter 
// provided, use that instead of the space character; pass "" or null to simply trim to a length.
// if ellipsis provided, append it if string was longer than length.
// "The quick brown fox".trimToWord( 11 ) == "The quick b"
// "The quick brown fox".trimToWord( 11, "..." ) == "The quick..."
String.prototype.trimToWord = function( trimToLength, ellipsis, delimiter )
{
    if ( this.length > trimToLength )
    {
        var temp = this.substring( 0, trimToLength );
        if ( delimiter )
        {
            if ( delimiter != "" ) temp = temp.substring( 0, temp.lastIndexOf( delimiter ) );
        }
        else 
        {
            if ( temp.indexOf( " " ) != -1 ) temp = temp.substring( 0, temp.lastIndexOf( " " ) );
        }
            
        if ( ellipsis ) temp += ellipsis;
    }
    else
    {
        var temp = this + "";
    }
    
    return temp;
}

function getQueryStringArgs()
{
    var args = new Object();
    var queryString = location.search.substring( 1 );
    var pairs = queryString.split("&");
    
    for ( var i = 0; i < pairs.length; i++ )
    {
        var pos = pairs[i].indexOf( "=" );
        if ( pos == -1 ) continue;
        var argName = pairs[i].substring( 0, pos );
        var argValue = pairs[i].substring( pos + 1 );
        argValue = decodeURIComponent( argValue );
        args[argName] = argValue;
    }
    return args;
}

function stringArrayToJSON ( array )
{
    var result = "[  ";
    for ( var i = 0 ; i < array.length ; i++ )
    {
        result += "\"" + array[i] + "\", ";
    }
    result = result.substring( 0, result.length - 2 ) + " ]";
    
    return result;
}

// calculate a contrasting color for outlining text on a poem
function outlineColorFromTextColor( textColor )
{
    var outlineColor = "#DDDDDD"; // assume a light gray outline
    if ( textColor.search( /#[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]/ ) != -1 ) // six-digit hex value?
    {
        var testColorValue = eval( "0x" + textColor.charAt( 1 ) ) + eval( "0x" + textColor.charAt( 3 ) ) +
             eval( "0x" + textColor.charAt( 5 ) );
        if ( testColorValue >= 19 ) outlineColor = "#222222"; // unless the text is also light
    }
    else if (( textColor.toLowerCase() == "white" ) || ( textColor.toLowerCase() == "silver" ))
    {
        outlineColor = "#222222";
    }
    
    return outlineColor;
}

function attachEventToElement ( element, eventName, handler, settingCapture )
{
    if ( settingCapture != true ) settingCapture = false;  // cast to Boolean
    
    switch ( eventName ) 
    {
    case "mousedown":
        if ( element.addEventListener ) { element.addEventListener( "mousedown", handler, settingCapture ); }
        else if ( element.attachEvent ) { element.attachEvent( "onmousedown", handler ); } 
        else { element.onmousedown = handler; }
        break;
        
    case "mouseup":
        if ( element.addEventListener ) { element.addEventListener( "mouseup", handler, settingCapture ); }
        else if ( element.attachEvent ) { element.attachEvent( "onmouseup", handler ); } 
        else { element.onmouseup = handler; }
        break;
        
    case "mouseover":
        if ( element.addEventListener ) { element.addEventListener( "mouseover", handler, settingCapture ); }
        else if ( element.attachEvent ) { element.attachEvent( "onmouseover", handler ); } 
        else { element.onmouseover = handler; }
        break;
    
    case "mouseout":
        if ( element.addEventListener ) { element.addEventListener( "mouseout", handler, settingCapture ); }
        else if ( element.attachEvent ) { element.attachEvent( "onmouseout", handler ); } 
        else { element.onmouseout = handler; }
        break;
    
    case "mousemove":
        if ( element.addEventListener ) { element.addEventListener( "mousemove", handler, settingCapture ); }
        else if ( element.attachEvent ) { element.attachEvent( "onmousemove", handler ); } 
        else { element.onmousemove = handler; }
        break;
    
    case "click":
        if ( element.addEventListener ) { element.addEventListener( "click", handler, settingCapture ); }
        else if ( element.attachEvent ) { element.attachEvent( "onclick", handler ); } 
        else { element.onclick = handler; }
        break;
    
    case "pageload":
        if ( element.addEventListener ) { element.addEventListener( "load", handler, settingCapture ); }
        else if ( element.attachEvent ) { element.attachEvent( "onload", handler ); }
        else { element.onload = handler; }
        break;
    
    case "keyup":
        if ( element.addEventListener ) { element.addEventListener( "keyup", handler, settingCapture ); }
        else if ( element.attachEvent ) { element.attachEvent( "onkeyup", handler ); }
        else { element.onkeyup = handler; }
        break;
    
    case "keypress":
        if ( element.addEventListener ) { element.addEventListener( "keypress", handler, settingCapture ); }
        // else if ( element.attachEvent ) { element.attachEvent( "onkeypress", handler ); }
        else { element.keypress = handler; }
        break;
    
    case "contextmenu":
        if ( element.addEventListener ) { element.addEventListener( "contextmenu", handler, settingCapture ); }
        else if ( element.attachEvent ) { element.attachEvent( "oncontextmenu", handler ); }
        else { element.contextmenu = handler; }
        break;
    
    }
}

function detachEventFromElement ( element, eventName, handler, capture )
{
    if ( capture != true ) capture = false;  // cast to Boolean
    
    switch ( eventName ) 
    {
    case "mousedown":
        if ( document.removeEventListener ) { document.removeEventListener( "mousedown", handler, capture ); }
        else if ( element.detachEvent ) { element.detachEvent( "onmousedown", handler ); }
        else { element.onmousedown = null; }
        break;
        
    case "mouseover":
        if ( document.removeEventListener ) { document.removeEventListener( "mouseover", handler, capture ); }
        else if ( element.detachEvent ) { element.detachEvent( "onmouseover", handler ); }
        else { element.onmouseover = null; }
        break;
    
    case "mousemove":
        if ( document.removeEventListener ) { document.removeEventListener( "mousemove", handler, capture ); }
        else if ( element.detachEvent ) { element.detachEvent( "onmousemove", handler ); }
        else { element.onmousemove = null; }
        break;
    
    case "mouseout":
        if ( document.removeEventListener ) { document.removeEventListener( "mouseout", handler, capture ); }
        else if ( element.detachEvent ) { element.detachEvent( "onmouseout", handler ); }
        else { element.onmouseout = null; }
        break;
    }
}

