//
// adjustTable
//      Adjusts how far the ink container table is from the left of the page,
//      based on how many ink containers are being displayed.
//
function adjustTable()
{
    var numContainers = parent.CommonJS.GetNumInkContainers();
    var table = document.getElementById('InkContainer');
    
    if (!numContainers || !table)
    {
        return false;
    }
    
    // Pixel values for the distance from the left came from the Printing
    // Status Style Guide, version 1.0.
    if (numContainers == 2)
    {
        designLeft = 75;
    }
    else if (numContainers == 4)
    {
        designLeft = 34;
    }
    else
    {
        designLeft = 0;
    }
    
    table.style.left = designLeft + "px";
}

//
// displayMessage
//      Finds the appropriate localized string within the page and
//      displays it in the message area.
//  Return:
//      A boolean value indicating whether the message was displayed
//      successfully or not.
//  Params:
//      id      Part of the ID of the element containing the message to
//              be displayed e.g. "CY".  The given level will determine
//              the rest of the element ID.  E.g. for a level of "low"
//              and an id of "CY", the resulting element ID would be "LCY".
//      level   The ink level for which a message should be displayed, e.g.
//              "verylow".
// 
function displayMessage(id, level)
{
    // Will be initialized later to the actual message to display,
    // e.g. "Black cartridge is low."
    var message = "";
    
    // Will be used to specify an ink level (e.g. low) in the message
    // ID.
    var prefix = "";
    
    // Where we'll insert the e.g. "Black ink low" message
    var displayArea = document.getElementById('Message');
    
    // Ensure the message area exists before we continue
    if (displayArea)
    {
        displayArea.innerText = "";
    }
    else
    {
        return false;
    }
    
    // Determine what prefix we should use in the message ID,
    // based on the ink level for these containers.
    if (level == "low")
    {
        prefix = "L";
    }
    else if (level == "verylow")
    {
        prefix = "V";
    }
    else
    {
        // Invalid level given
        return false;
    }
    
    // Sometimes the containers will be in a different order than
    // the ID's, so we end up with something like LYC when the
    // actual element ID is LCY.  This will return the correct
    // order (e.g. CY), based on a pattern.
    id = prefix + reorderID(id);
    
    // Initialized to the page element containing the message, e.g.
    // "Black cartridge is low", and we're going to stick that string
    // in the message area
    var msgElement = document.getElementById(id);
    
    // If the element containing the warning message exists...
    if (msgElement)
    {
        // Get the warning message!
        message = msgElement.innerText;
        
        // If the message isn't blank...
        if ("" != message)
        {
            // Display the warning message in the display area
            displayArea.innerText = message;
        }
        // Otherwise, the message is blank...
        else
        {
            return false;
        }
    }
    // Otherwise, the element containing the warning message doesn't
    // exist...
    else
    {
        return false;
    }
    
    return true;
}

//
// displayPartNums
//      Displays part numbers for each ink container being displayed.
//  Return:
//      A boolean value indicating whether the part numbers were displayed
//      successfully or not.
// 
function displayPartNums()
{
    // Get a string of this format:
    // position1-partNum1 position2-partNum2 ... positionX-partNumX
    // e.g. 1-30 2-33
    var positionsPartNumsStr = parent.CommonJS.GetPartNums();
    
    if (!positionsPartNumsStr)
    {
        return false;
    }
    
    // Split up the pairs so that we have an array like this:
    // [position1-partNum1, position2-partNum2, ..., positionX-partNumX]
    var positionsPartNums = positionsPartNumsStr.split(" ");
    
    // The total number of container/part number pairs
    var total = positionsPartNums.length;
    
    var position, partNum, arr;
    var id = "";
    var partNumArea;
    
    // Go through each position/part number pair
    for (var i=0; i<total; i++)
    {
        // Split apart the position-partNum string
        arr = positionsPartNums[i].split("-");
        position = arr[0];
        partNum = arr[1];
        
        if (
            "1" == position ||
            "2" == position ||
            "3" == position ||
            "4" == position
        )
        {
            id = "partNum" + position;
        }
        // Current position in the array is unrecognized/invalid
        else {
            continue;
        }
        
        partNumArea = document.getElementById(id);
        
        // If an element with that ID exists...
        if (partNumArea)
        {
            // Stick the part number inside that element
            partNumArea.innerText = partNum;
        }
    }
    
    return true;
}

//
// getContainers
//      Get an array of ink containers that are being displayed.
//  Return:
//      An array of strings that represent ink containers (e.g. "tank_black")
//      that have the desired (as indicated by the parameter) level of ink.
//      Will be false if there is a problem.
//  Params:
//      level   The ink level that we're concerned with, e.g. "verylow".
//
function getContainers(level)
{
    var containersStr;

    if (level == "low")
    {
        // Get a space-separated string of the ink containers with a
        // low ink level
        containersStr = parent.CommonJS.GetLowContainers();
    }
    else if (level == "verylow")
    {
        // Get a space-separated string of the ink containers with a
        // very low ink level
        containersStr = parent.CommonJS.GetVeryLowContainers();
    }
    else
    {
        return false;
    }
    
    // If there is no string of containers, then there aren't
    // any containers at the desired ink level.  This shouldn't happen,
    // because the billboard that calls this Javascript
    // shouldn't show up unless there ARE low ink containers, but it's
    // good to be cautious.
    if (!containersStr)
    {
        return false;
    }
    
    // Split the space-separated string of containers into an array.
    return containersStr.split(" ");
}

//
// handleOrderInk
//      Hides the Order Ink button if necessary.
//  Return:
//      True or false, depending on whether the button was shown/hidden
//      successfully or not.
//
function handleOrderInk()
{
    // Find out whether we should show the button or not
    var show = parent.CommonJS.GetShowOrderInk();
    
    // If we should show the button, then exit out because we needn't do
    // anything else--it's shown by default.
    if (show)
    {
        return true;
    }
    
    // Grab the button
    var button = document.getElementById('OrderInk');
    
    // If the button wasn't found, return false because that's a problem.
    if (!button)
    {
        return false;
    }
    
    // Hide the button.
    button.style.display = "none";
    
    // Return true to indicate all is well.
    return true;
}

//
// init
//      Makes appropriate function calls to move the ink container table around
//      in order to center it, display part numbers for each ink container,
//      hide the Order Ink button, and display the low/very low ink warning
//      message.
//  Return:
//      True or false, depending on whether everything executed successfully.
//  Params:
//      level   The ink level we're to work with, e.g. "low" or "status".
//
function init(level)
{
    // Display the part numbers for all containers
    displayPartNums();
    
    // Show or hide the 'Order Ink' button, depending on result
    // returned from CommonJS
    handleOrderInk();
    
    // Depending on whether we're showing 2 tanks/cartridges or 4,
    // the container-holding table is positioned differently from
    // the left side.
    adjustTable();
    
    // If we're only checking the status of the ink containers, we
    // don't need to do anything else with Javascript because there
    // aren't any ink level warnings to display.
    if ("status" == level)
    {
        return true;
    }
    
    // Get an array of low or very low (depending on the given level)
    // container strings (e.g. ["tank_black", "tank_magenta"])
    var containers = getContainers(level);
    
    // Ensure we got back a nice array and not a false, which would
    // indicate something went awry.
    if (!containers)
    {
        return false;
    }
    
    // The number of ink containers
    var numContainers = containers.length;
    
    // Will be used to hold the current container that we've reached
    // in the array of containers.
    var container;
    
    // The ID that will pinpoint the message element based on which tanks
    // or cartridges are low.
    // Key:
    //    L - low           K - black
    //    V - very low      C - cyan
    //                      M - magenta
    //                      Y - yellow
    //                      P - photo
    //                      O - color (color cartridge/tri-color tank)
    var msgID = "";
    
    // Iterate through all the containers
    for (var i=0; i<numContainers; i++)
    {
        container = containers[i];
        
        // Current container in the array is a black tank or
        // cartridge
        if (container == "tank_black" || container == "black")
        {
            msgID += "K";
        }
        // Current container in the array is a cyan tank
        else if (container == "tank_cyan")
        {
            msgID += "C";
        }
        // Current container in the array is a magenta tank
        else if (container == "tank_magenta")
        {
            msgID += "M";
        }
        // Current container in the array is a yellow tank
        else if (container == "tank_yellow")
        {
            msgID += "Y";
        }
        // Current container is a tri-color tank or a color cartridge
        else if (container == "tank_tricolor" || container == "color")
        {
            msgID += "O";
        }
        // Current container is a photo cartridge
        else if (container == "photo")
        {
            msgID += "P";
        }
        // Current container in the array is unrecognized/invalid
        else
        {
            continue;
        }
    }
    
    // Attempt to display the warning message that is found in the
    // element with ID msgID.
    var result = displayMessage(msgID, level);
    
    return result;
}

//
// reorderID
//      Given a message ID (e.g. KYM, representing containers black,
//      yellow, and magenta), this will return an equivalent ID, only
//      in the correct order (i.e. based on the ordering used in
//      bbstrings.xml).  The correct order for KYM would be KMY.
//  Return:
//      msgID   The reordered message ID, matching some ID in bbstrings.xml.
//              This message ID will NOT include the character representing
//              the ink level, e.g. L for "low".
//  Params:
//      msgID   The initial ordering of the message ID, which does NOT
//              include the character representing the ink level, e.g. V for
//              "verylow".
//
function reorderID(msgID)
{
    // Regular expressions to match the representative letter for
    // each kind of container.
    var blackRegex = new RegExp('K');
    var cyanRegex = new RegExp('C');
    var magentaRegex = new RegExp('M');
    var yellowRegex = new RegExp('Y');
    var photoRegex = new RegExp('P');
    var colorRegex = new RegExp('O');
    
    // The order here is based on the order in bbstrings.xml.  That is,
    // the key for a string of black, magenta, and yellow would be KMY,
    // and not KYM or YKM or any other variation.  Hence, K comes before
    // M and M comes before Y in this if-else set.
    if (blackRegex.test(msgID))
    {
        // Recursively build up the correct order of the message ID.
        return "K" + reorderID(msgID.replace(blackRegex, ""));
    }
    else if (cyanRegex.test(msgID))
    {
        return "C" + reorderID(msgID.replace(cyanRegex, ""));
    }
    else if (magentaRegex.test(msgID))
    {
        return "M" + reorderID(msgID.replace(magentaRegex, ""));
    }
    else if (yellowRegex.test(msgID))
    {
        return "Y" + reorderID(msgID.replace(yellowRegex, ""));
    }
    else if (photoRegex.test(msgID))
    {
        return "P" + reorderID(msgID.replace(photoRegex, ""));
    }
    else if (colorRegex.test(msgID))
    {
        return "O" + reorderID(msgID.replace(colorRegex, ""));
    }
    // If the string doesn't match any of the regular expressions, just
    // return it as it is.
    else
    {
        return msgID;
    }
}