/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/

// Shared UI parameters
global int $g_heightPerRow = 29;
global int $g_controlHeight = 22;
global string $g_lastRow = "";

LumberyardAnimationManagerLoadDependencies();

//! Loads all scripts that the Animation Manager relies on.
global proc LumberyardAnimationManagerLoadDependencies()
{
    eval("source cryAnim.mel");
    eval("source LumberyardUtilities.mel");
}

//! Creates the title row for the Animation Manager.
/*! 
 \note
  This will contain the column titles for all animation data. If you choose to customize animation data, and want to expose it to the
  Animation Manager, you will want to create a new column here as well as when you create the data.
 \sa LumberyardAnimationManagerCreateUIRow() 
*/
proc LumberyardAnimationManagerCreateColumnTitles()
{
    global int $g_controlHeight;
    setParent LUMBERYARDANIMATIONMANAGER_MAINLAYOUT;
    
    rowLayout -numberOfColumns 3 -columnWidth3 35 805 35 -backgroundColor 0.26 0.26 0.26
        -columnAlign 1 "center" -columnAttach 1 "both" 0 - columnAlign 2 "center" -columnAttach 2 "both" 0
        -columnAlign 3 "center" -columnAttach 3 "both" 0;

    // For <> button column
    text -height $g_controlHeight -label "";
    
    // Main animation columns;
    rowLayout -numberOfColumns 6 -columnWidth6 35 35 150 150 150 250 -adjustableColumn 6 -backgroundColor 0.26 0.26 0.26
        -columnAlign 1 "center" -columnAttach 1 "both" 0 -columnAlign 2 "center" -columnAttach 2 "both" 0
        -columnAlign 3 "center" -columnAttach 3 "both" 0 -columnAlign 4 "center" -columnAttach 4 "both" 0
        -columnAlign 5 "center" -columnAttach 5 "both" 0 -columnAlign 6 "center" -columnAttach 6 "both" 0 LUMBERYARDTOOL_ANIMMANAGER_COLUMNTITLES;
    {
        text -height $g_controlHeight -label "Start";
        text -height $g_controlHeight -label "End";
        text -height $g_controlHeight -label "Name";
        text -height $g_controlHeight -label "Root Node";
        text -height $g_controlHeight -label "Animation Layers";
        text -height $g_controlHeight -label "Export Path";
        setParent ..;
    }
    
    // For the +/X buttons
    text -height $g_controlHeight -label "";
}

//! Resize the Animation Manager window.
/*!
 \param $newExportListHeight The new height for the columnLayout containing the animation export data
 \param $newWindowListHeight The new height for the Animation Manager window
*/
global proc LumberyardAnimationManagerResize(int $newExportListHeight, int $newWindowHeight)
{
    columnLayout -edit -height $newExportListHeight LUMBERYARDANIMATIONMANAGER_EXPORT_SCROLLLAYOUT;
    columnLayout -edit -height $newWindowHeight LUMBERYARDANIMATIONMANAGER_MAINLAYOUT;
    window -edit -height $newWindowHeight LUMBERYARDANIMATIONMANAGER_WINDOW;
}

//! Change the height of the Animation Manager and export list by a fixed delta.
/*!
 \param $heightDelta Offset to change height of elements by. Can be positive or negative.
 \note 
  This is a utility function used to simplify the logic in several places where determining an offset is
  far less expensive than recalculating the desired height from scratch. It should be preferred over
  LumberyardAnimationManagerResize in such cases.
 \sa LumberyardAnimationManagerResize()
*/
proc LumberyardAnimationManagerChangeHeight(int $heightDelta)
{
    int $exportListHeight = `columnLayout -query -height LUMBERYARDANIMATIONMANAGER_EXPORT_SCROLLLAYOUT`;
    int $windowHeight = `window -query -height LUMBERYARDANIMATIONMANAGER_WINDOW`;
    
    $windowHeight = $windowHeight + $heightDelta;
    $exportListHeight = $exportListHeight + $heightDelta;
    
    LumberyardAnimationManagerResize($exportListHeight, $windowHeight);
}

//! Wrapper command used to remove the export data for an animation being managed by the Animation Manager.
/*!
 /param $row The name of the row UI element corresponding to the export data to be removed.
*/
global proc LumberyardAnimationManagerRemoveItem(string $row)
{
    string $managedNode = `rowLayout -query -annotation $row`;
    LumberyardUtilitiesDeleteAnimationExport($managedNode);
}

//! Open a file browser dialog and update the export path for an animation based on selection.
/*!
 /param $row The name of the rowLayout UI element corresponding to the export data to be updated.
 /param $textField The name of the text field UI element corresponding to the export data to be updated.
*/
global proc LumberyardAnimationManagerFolderBrowser(string $row, string $textField)
{
    string $managedNode = `rowLayout -query -annotation $row`;
    string $currentPath = `LumberyardUtilitiesGetAnimationExportPath $managedNode`;
    
    if ($currentPath == "")
    {
        $currentPath = `file -query -sceneName`;
        $currentPath = `dirname $currentPath`;
    }
    
    string $result[] = `LumberyardBrowseForPath $currentPath "Set Export Path"`;
    // We need to requery this in case this took focus from the name text box
    $managedNode = `rowLayout -query -annotation $row`; 
    
    if (size($result) == 1)
    {
        // Update the UI
        textField -edit -text $result[0] $textField;
        // Update the data
        LumberyardUtilitiesSetAnimationExportPath($managedNode, $result[0]);
    }
}

//! Update the root joint of the export data and the UI based on current selection in Maya.
/*!
 /param $row The name of the rowLayout UI element corresponding to the export data to be updated.
 /param $textField The name of the textField UI element corresponding to the export data to be updated.
*/
global proc LumberyardAnimationManagerGetRootJointFromSelection(string $row, string $textField)
{
    string $managedNode = `rowLayout -query -annotation $row`;
    string $currentRootJoint = `LumberyardUtilitiesGetAnimationRootJoint $managedNode`;
    
    $currentRootJoint = `GetRootJointForSelection $currentRootJoint`;
    
    // Update the UI
    textField -edit -text $currentRootJoint $textField;
    // Update the data
    LumberyardUtilitiesSetAnimationRootJoint($managedNode, $currentRootJoint);
}

//! Utility function to get the name of a UI control in the nested rowLayouts used in Animation Manager.
/*!
 \param $row Root rowLayout corresponding to a single animation export.
 \param $indices The sequence of indices used to index into nested rowLayouts.
 \note If you are changing the layout in any way, be aware that calls to this function many need to be updated.
 \sa LumberyardAnimationManagerGetStartFrame(), LumberyardAnimationManagerGetEndFrame(), LumberyardAnimationManagerGetExportName(), LumberyardAnimationManagerGetRootJoint(), and LumberyardAnimationManagerGetExportPath()
*/
proc string LumberyardAnimationManagerGetRowControl(string $row, int $indices[])
{
    string $control = $row;
    
    if(size($indices) == 0)
    {
        return "";
    }
    
    for($index in $indices)
    {
        if(!`rowLayout -query -exists $control`)
        {
           return "";
        }
        string $children[] = `rowLayout -query -childArray $control`;
        if($index >= size($children))
        {
            return "";
        }
        $control = $control + "|" + $children[$index];
    }
    
    return $control;
}

//! Get the value contained in the start frame intField in an animation export rowLayout.
/*!
 \param $row The name of the rowLayout UI element containing the intField to query
*/
global proc int LumberyardAnimationManagerGetStartFrame(string $row)
{
    int $startFrame = -1;
    int $controlMapping[] = {1, 0};
    string $control = `LumberyardAnimationManagerGetRowControl $row $controlMapping`;
    if($control != "" && `intField -query -exists $control`)
    {
        $startFrame = `intField -query -value $control`;
    }
    return $startFrame;
}

//! Get the value contained in the end frame intField in an animation export rowLayout.
/*!
 \param $row The name of the rowLayout UI element containing the intField to query
*/
global proc int LumberyardAnimationManagerGetEndFrame(string $row)
{
    int $endFrame = -1;
    int $controlMapping[] = {1, 1};
    string $control = `LumberyardAnimationManagerGetRowControl $row $controlMapping`;
    if($control != "" && `intField -query -exists $control`)
    {
        $endFrame = `intField -query -value $control`;
    }
    return $endFrame;
}

//! Get the value contained in the export name textField in an animation export rowLayout.
/*!
 \param $row The name of the rowLayout UI element containing the textField to query
*/
global proc string LumberyardAnimationManagerGetExportName(string $row)
{
    string $exportName = "";
    int $controlMapping[] = {1, 2};
    string $control = `LumberyardAnimationManagerGetRowControl $row $controlMapping`;
    if($control != "" && `textField -query -exists $control`)
    {
        $exportName = `textField -query -text $control`;
    }
    return $exportName;
}

//! Get the value contained in the root joint textField in an animation export rowLayout.
/*!
 \param $row The name of the rowLayout UI element containing the textField to query
*/
global proc string LumberyardAnimationManagerGetRootJoint(string $row)
{
    string $rootJoint = "";
    int $controlMapping[] = {1, 3, 0};
    string $control = `LumberyardAnimationManagerGetRowControl $row $controlMapping`;
    if($control != "" && `textField -query -exists $control`)
    {
        $rootJoint = `textField -query -text $control`;
    }
    return $rootJoint;
}

//! Get the value contained in the export path textField in an animation export rowLayout.
/*!
 \param $row The name of the rowLayout UI element containing the textField to query
*/
global proc string LumberyardAnimationManagerGetExportPath(string $row)
{
    string $exportPath = "";
    int $controlMapping[] = {1, 5, 0};
    string $control = `LumberyardAnimationManagerGetRowControl $row $controlMapping`;
    if($control != "" && `textField -query -exists $control`)
    {
        $exportPath = `textField -query -text $control`;
    }
    return $exportPath;
}

/////////////////////////////////////////////////////////////////////
// Functions to transmit UI changes to the data backend

//! Transmit value contained in the start frame UI to the data backend.
/*!
 \param $row The name of the rowLayout UI element corresponding to the data to be updated.
*/
global proc LumberyardAnimationManagerUpdateStartFrame(string $row)
{
    string $managedNode = `rowLayout -query -annotation $row`;
    int $startFrame = `LumberyardAnimationManagerGetStartFrame $row`;
    LumberyardUtilitiesSetAnimationStartFrame($managedNode, $startFrame);
}

//! Transmit value contained in the end frame UI to the data backend.
/*!
 \param $row The name of the rowLayout UI element corresponding to the data to be updated.
*/
global proc LumberyardAnimationManagerUpdateEndFrame(string $row)
{
    string $managedNode = `rowLayout -query -annotation $row`;
    int $endFrame = `LumberyardAnimationManagerGetEndFrame $row`;
    LumberyardUtilitiesSetAnimationEndFrame($managedNode, $endFrame);
}

//! Transmit value contained in the export name UI to the data backend.
/*!
 \param $row The name of the rowLayout UI element corresponding to the data to be updated.
*/
global proc LumberyardAnimationManagerUpdateExportName(string $row)
{
    string $managedNode = `rowLayout -query -annotation $row`;

    string $newExportName = `LumberyardAnimationManagerGetExportName $row`;
    LumberyardUtilitiesSetAnimationExportName( $managedNode, $newExportName);
}

//! Transmit value contained in the root joint UI to the data backend.
/*!
 \param $row The name of the rowLayout UI element corresponding to the data to be updated.
*/
global proc LumberyardAnimationManagerUpdateRootJoint(string $row)
{
    string $managedNode = `rowLayout -query -annotation $row`;
    string $rootJoint = `LumberyardAnimationManagerGetRootJoint $row`;
    LumberyardUtilitiesSetAnimationRootJoint($managedNode, $rootJoint);
}

//! Transmit value contained in the export path UI to the data backend.
/*!
 \param $row The name of the rowLayout UI element corresponding to the data to be updated.
*/
global proc LumberyardAnimationManagerUpdateExportPath(string $row)
{
    string $exportPath = `LumberyardAnimationManagerGetExportPath $row`;
    string $managedNode = `rowLayout -query -annotation $row`;
    string $finalExportPath = `LumberyardUtilitiesSetAnimationExportPath $managedNode $exportPath`;
    if($exportPath != $finalExportPath)
    {
        int $controlMapping[] = {1, 5, 0};
        string $control = `LumberyardAnimationManagerGetRowControl $row $controlMapping`;
        textField -edit -text $finalExportPath $control;
    }
}

//! Sets the animLayer selection in the data backend based on the current UI state.
/*!
 \param $row The name of the rowLayout UI element corresponding to the animation export data to update.
 \param $layerPullDown the frameLayout containing the UI data that will be transmitted.
*/
global proc LumberyardAnimationManagerUpdateExportLayers(string $row, string $layerPullDown)
{
    string $managedNode = `rowLayout -query -annotation $row`;
    string $children[] = `frameLayout -query -childArray $layerPullDown`;
    string $activeLayers[];
    
    for($child in $children)
    {
        string $controls[] = `rowLayout -query -childArray $child`;
        int $checked = `checkBox -query -value $controls[0]`;
        if($checked)
        {
            string $layerName = `text -query -label $controls[1]`;
            $activeLayers[size($activeLayers)] = $layerName;
        }
    }
    
    LumberyardUtilitiesSetAnimationExportLayers($managedNode, $activeLayers);
    LumberyardAnimationManagerSetLayerListTitle($row, $layerPullDown);
}

///////////////////////////////////////////////////////////////////////
// UI Update calls for layout and default values

//! Identifies and stores the last export node rowLayout in the Animation Manager.
/*!
 /note This stored value is used to poll for default values when creating new rows
*/
global proc LumberyardAnimationManagerUpdateLastRow()
{
    global string $g_lastRow;
    
    string $children[] = `columnLayout -query -childArray LUMBERYARDANIMATIONMANAGER_EXPORT_SCROLLLAYOUT`;

    if (size($children) == 0)
    {
        $g_lastRow = "";
    }
    else
    {
        $g_lastRow = $children[(size($children)) - 1];
    }
}

//! Gets the default export path for newly added items in the Animation Manager.
/*!
 \note
  The default path will be that of the last row in the Animation Manager. If there are no
  rows present in the Animation Manager, the path will default to the top level path for the engine
  installation. (i.e. the directory containing Bin64, Code, etc.)
 \todo
  Consider setting the default path based on the sys_game_folder in setup.cfg instead of the root
  engine path.
*/
proc string LumberyardAnimationManagerGetDefaultExportPath()
{
    global string $g_lastRow;
    string $exportPath = "";
    
    if($g_lastRow != "")
    {
        string $managedNode = `rowLayout -query -annotation $g_lastRow`;
        $exportPath = `LumberyardUtilitiesGetAnimationExportPath $managedNode`;
    }
    
    // if this is the first time we create a row, start at the parent directory for the engine
    if ($exportPath == "")
    {
        $exportPath = eval("getenv \"LY_MAYA_PLUG_IN_PATH\"");
        // equivalent to ../../../
        for($i = 0; $i < 3; $i++)
        {
            $exportPath = `dirname $exportPath`;
        }
        $exportPath = `cryExportFixupPath $exportPath`;
    }
    
    return $exportPath;
}

//! Gets the default root joint for newly added items in the Animation Manager.
/*!
 \note
  The default root joint will be that of the last row in the Animation Manager. If there are no
  rows present in the Animation Manager, the root joint will default to an empty string.
 \todo Consider using selection as default root joint if the first selected item is a joint.
*/
proc string LumberyardAnimationManagerGetDefaultRootJoint()
{
    global string $g_lastRow;
    string $rootJoint = "";
    
    if($g_lastRow != "")
    {
        string $managedNode = `rowLayout -query -annotation $g_lastRow`;
        $rootJoint = `LumberyardUtilitiesGetAnimationRootJoint $managedNode`;
    }
    
    return $rootJoint;
}

//! Calculates the correct UI heights based on the number of animation exports.
/*!
 \note 
  This is only called when first creating the Animation Manager. It is more expensive, and should only be used if you
  cannot calculate the size offset.
 \sa LumberyardAnimationManagerUpdateHeight()
*/
global proc LumberyardAnimationManagerUpdateHeight()
{
    global int $g_heightPerRow;
    $childCount = `columnLayout -query -numberOfChildren LUMBERYARDANIMATIONMANAGER_EXPORT_SCROLLLAYOUT`;
    $newExportListHeight = ($childCount * $g_heightPerRow) + 1;
    // For the title and add rows
    $childCount = $childCount + 2;
    $newWindowHeight = ($childCount * $g_heightPerRow) + 2;
    LumberyardAnimationManagerResize $newExportListHeight $newWindowHeight;
}

//! Get the selected animLayers for an animation export from the data backend.
/*!
 \param $row The name of the rowLayout corresponding to the animation export to fetch the data for.
*/
proc string[] LumberyardAnimationManagerGetSelectedLayers(string $row)
{
    string $managedNode = `rowLayout -query -annotation $row`;
    string $exportLayers[] = `LumberyardUtilitiesGetAnimationExportLayers $managedNode`;
    
    return $exportLayers;
}

//! Callback to keep the animLayer selections in the UI and data backend synchronized with Maya's animLayer state.
/*!
 \note This callback occurs when an animLayer is renamed, moved, deleted, or added.
 \todo 
  This currently forces a full UI redraw, which collapses any open animLayer frameLayouts. We should preserve expanded
  state for each row during UI rebuilds.
*/
global proc LumberyardAnimationManagerUpdateLayers()
{
    LumberyardUtilitiesUpdateAnimationLayers();
    LumberyardAnimationManagerReadExports();
}

//! Updates the animLayer frameLayout title based on the number of animLayers selected for an animation export.
/*!
 \param $row The name of the UI rowLayout corresponding to the animation export data to query.
 \param $layerPullDown The name of the UI frameLayout whose title should be updated.
*/
global proc LumberyardAnimationManagerSetLayerListTitle(string $row, string $layerPullDown)
{
    string $layers[];
    
    $layers = `LumberyardAnimationManagerGetSelectedLayers $row`;
    int $count = size($layers);
    
    string $newTitle = "Select Layers";
    if($count > 0)
    {
        $newTitle = "Selected "+$count;
    }
    
    frameLayout -edit -label $newTitle $layerPullDown;
}

//! Callback to fill the animLayer frameLayout when the user expands it.
/*!
 \param $row The name of the rowLayout UI element corresponding to the animation export data to fetch.
 \param $layerPullDown The frameLayout UI element that will be populated.
 \note This will also handle adjusting UI heights to accommodate the number of animLayers displayed.
*/
global proc LumberyardAnimationManagerExpandLayerList(string $row, string $layerPullDown)
{
    global int $g_controlHeight;
    global int $g_heightPerRow;
    setParent $layerPullDown;
    
    string $animLayers[] = `LumberyardUtilitiesGetAnimLayers`;
    int $layerCount = size($animLayers);
    // +1 to handle frameLayout title
    int $newHeight = $g_controlHeight * ($layerCount + 1);
    int $parentWidth = `frameLayout -query -width $layerPullDown`;
    if($layerCount == 0)
    {
        $newHeight = $g_controlHeight * 2;
        text -align "left" -label "<No Layers Found>" -width $parentWidth;
    }
    LumberyardAnimationManagerChangeHeight($newHeight - $g_controlHeight);
    frameLayout -edit -height $newHeight $layerPullDown;
    rowLayout -edit -height ($newHeight + $g_heightPerRow - $g_controlHeight) $row;
    
    string $layers[] = `LumberyardAnimationManagerGetSelectedLayers $row`;
    
    for($i = 0; $i < $layerCount; $i++)
    {
        int $enabled = ($animLayers[$i] != "BaseAnimation");
        int $value = `stringArrayContains $animLayers[$i] $layers`;
        rowLayout -height $g_controlHeight -width $parentWidth -numberOfColumns 2;
        checkBox -label "" -value $value -backgroundColor 0.5 0.5 0.5 -enable $enabled -enableBackground $enabled 
            -changeCommand ("LumberyardAnimationManagerUpdateExportLayers " + $row + " " + $layerPullDown);
        text -align "left" -label $animLayers[$i] -width ($parentWidth - $g_controlHeight);
        setParent ..;
    }
}

//! Callback used to adjust UI height when user collapses an animLayer frameLayout.
/*
 \param $row The name of the rowLayout UI element whose animLayer pulldown is being collapsed
 \param $layerPullDown the name of the frameLayout UI element being collapsed
*/
global proc LumberyardAnimationManagerCollapseLayerList(string $row, string $layerPullDown)
{
    global int $g_controlHeight;
    global int $g_heightPerRow;
    
    int $currentRowHeight = `rowLayout -query -height $row`;
    int $heightDiff = $currentRowHeight - $g_heightPerRow;
    $heightDiff = 0 - $heightDiff;
    
    string $children[] = `frameLayout -query -childArray $layerPullDown`;
    for($child in $children)
    {
        deleteUI $child;
    }
    
    LumberyardAnimationManagerChangeHeight($heightDiff);
    rowLayout -edit -height $g_heightPerRow $row;
    frameLayout -edit -height $g_controlHeight $layerPullDown;
}

//! Creates a new UI rowLayout in the Animation Manager corresponding to an animation export node.
/*!
 \param $exportNode The name of the exportNode in the sceneName
 \note 
  No guarantee is made about avoiding multiple rows referring to the same export node, so it is
  incumbent on the caller to ensure that this does not occur. The layout of the UI row is heavily
  integrated into several other UI components, so it will need to be updated if any new data is 
  exposed to the Animation Manager. The row maintains a string reference to the name of the data
  node that it corresponds to in the annotation field. It is very important that these nodes are
  not renamed outside the tool flow, or the UI will not be able to fetch or manipulate data until
  a full UI rebuild.
 \sa LumberyardAnimationManagerCreateColumnTitles(), LumberyardAnimationManagerGetRowControl()
*/
global proc LumberyardAnimationManagerCreateUIRow(string $exportNode)
{
    global int $g_controlHeight;
    global string $g_lastRow;
    global float $g_UIColor[];
    
    if(!`LumberyardUtilitiesAnimationExportIsValid($exportNode)`)
    {
        return;
    }
    
    int $startFrame = getAttr($exportNode+".startFrame");
    int $endFrame = getAttr($exportNode+".endFrame");
    string $exportName = getAttr($exportNode+".exportName");
    string $rootJoint = getAttr($exportNode+".rootJoint");
    string $exportPath = getAttr($exportNode+".exportPath");
    
    setParent LUMBERYARDANIMATIONMANAGER_EXPORT_SCROLLLAYOUT;

    $newRow = `rowLayout -numberOfColumns 3 -columnWidth3 35 805 35 -backgroundColor 0.26 0.26 0.26
        -columnAlign 1 "center" -columnAttach 1 "both" 0 -rowAttach 1 "top" 2
        -columnAlign 2 "center" -columnAttach 2 "both" 0 -rowAttach 2 "top" 0
        -columnAlign 3 "center" -columnAttach 3 "both" 0 -rowAttach 3 "top" 2 -annotation $exportNode`;

    //Sets the start and end frame for an animation export to match the Maya timeline 
    button -height $g_controlHeight -label "<>" -annotation "Sets the start and end frame for an animation export to match the Maya timeline." -backgroundColor $g_UIColor[0] $g_UIColor[1] $g_UIColor[2]
        -command ("LumberyardUtilitiesSnapAnimationToTimeline " + $exportNode);
    
    // Main animation columns;
    rowLayout -numberOfColumns 6 -columnWidth6 35 35 150 150 150 350 -adjustableColumn 6 -backgroundColor 0.26 0.26 0.26
        -columnAlign 1 "center" -columnAttach 1 "both" 0 -rowAttach 1 "top" 0
        -columnAlign 2 "center" -columnAttach 2 "both" 0 -rowAttach 2 "top" 0
        -columnAlign 3 "center" -columnAttach 3 "both" 0 -rowAttach 3 "top" 0
        -columnAlign 4 "center" -columnAttach 4 "both" 0 -rowAttach 4 "top" 0
        -columnAlign 5 "center" -columnAttach 5 "both" 0 -rowAttach 5 "top" 3 
        -columnAlign 6 "center" -columnAttach 6 "both" 0 -rowAttach 6 "top" 0;
    {
        // Start Frame
        string $startFrameControl = `intField -height $g_controlHeight -value $startFrame -backgroundColor 0 0 0 -changeCommand ("LumberyardAnimationManagerUpdateStartFrame " + $newRow)`;
        
        // End Frame
        string $endFrameControl = `intField -height $g_controlHeight -value $endFrame -backgroundColor 0 0 0 -changeCommand ("LumberyardAnimationManagerUpdateEndFrame " + $newRow)`;
        
        // Export Name
        string $exportNameControl = `textField -height $g_controlHeight -text $exportName -backgroundColor 0 0 0 -changeCommand ("LumberyardAnimationManagerUpdateExportName " + $newRow)`;
        
        // Root Joint     
        rowLayout -numberOfColumns 2 -columnWidth 128 $g_controlHeight -backgroundColor 0.26 0.26 0.26
            -columnAlign 1 "center" -columnAttach 1 "both" 0 -columnAlign 2 "center" -columnAttach 2 "both" 0;
        {
            string $rootJointControl = `textField -height $g_controlHeight -width 128 -text $rootJoint -backgroundColor 0 0 0 -changeCommand ("LumberyardAnimationManagerUpdateRootJoint " + $newRow)`;
            button -height $g_controlHeight -label "+" -backgroundColor $g_UIColor[0] $g_UIColor[1] $g_UIColor[2]
                -command ("LumberyardAnimationManagerGetRootJointFromSelection " + $newRow + " " + $rootJointControl);
            setParent ..;
        }
        
        // Animation Layers
        $layerPullDown = `frameLayout -height $g_controlHeight -width 150 -collapsable true -collapse true`;
        frameLayout -edit -preExpandCommand ("LumberyardAnimationManagerExpandLayerList " + $newRow + " " + $layerPullDown) $layerPullDown;
        frameLayout -edit -preCollapseCommand ("LumberyardAnimationManagerCollapseLayerList " + $newRow + " " + $layerPullDown) $layerPullDown;
        LumberyardAnimationManagerSetLayerListTitle($newRow, $layerPullDown);
        setParent ..;
        
        // Export Path
        rowLayout -numberOfColumns 2 -columnWidth 228 $g_controlHeight -backgroundColor 0.26 0.26 0.26
            -columnAlign 1 "center" -columnAttach 1 "both" 0 -columnAlign 2 "center" -columnAttach 2 "both" 0;
        {
            string $exportPathControl = `textField -height $g_controlHeight -width 248 -text $exportPath -backgroundColor 0 0 0 -changeCommand ("LumberyardAnimationManagerUpdateExportPath " + $newRow)`;
            iconTextButton -image "icons/lumberyard_folder_icon.png" -height $g_controlHeight -width 20 -backgroundColor $g_UIColor[0] $g_UIColor[1] $g_UIColor[2]
                -command ("LumberyardAnimationManagerFolderBrowser " + $newRow + " " + $exportPathControl);
            setParent ..;
        }
        setParent ..;
    }
    
    button -height $g_controlHeight -label "X" -backgroundColor $g_UIColor[0] $g_UIColor[1] $g_UIColor[2]
        -command ("LumberyardAnimationManagerRemoveItem " + $newRow);
    $g_lastRow = $newRow;
}

//! Creates all required elements when a new animation export is requested.
/*!
 \note 
  Determines the default values for a new node, creates it in the data backend, 
  and generates the UI elements for it.
*/
global proc LumberyardAnimationManagerAddNewItem()
{
    int $startFrame = `playbackOptions -query -minTime`;
    int $endFrame = `playbackOptions -query -maxTime`;
    string $exportName = `LumberyardUtilitiesGetUniqueAnimationName ""`;
    string $rootJoint = `LumberyardAnimationManagerGetDefaultRootJoint`;
    string $exportPath = `LumberyardAnimationManagerGetDefaultExportPath`;
    string $exportLayers[] = `LumberyardUtilitiesGetAnimLayers`;
    
    LumberyardUtilitiesCreateAnimationExport($startFrame, $endFrame, $exportName, $rootJoint, $exportPath, $exportLayers);
    
    LumberyardUtilitiesUpdateAnimationUI();
}

//! Creates the + button in the lower right of the Animation Manager which will generate new animation exports when clicked
global proc LumberyardAnimationManagerCreateAddButton()
{
    global int $g_controlHeight;
    global float $g_UIColor[];
    
    if(`rowLayout -exists LUMBERYARDANIMATIONMANAGER_ADDITEM_ROW`)
    {
        deleteUI LUMBERYARDANIMATIONMANAGER_ADDITEM_ROW;
    }
    setParent LUMBERYARDANIMATIONMANAGER_MAINLAYOUT;

    rowLayout -numberOfColumns 3 -columnWidth3 35 806 35 -backgroundColor 0.26 0.26 0.26
        -columnAlign 1 "center" -columnAttach 1 "both" 0 - columnAlign 2 "center" -columnAttach 2 "both" 0
        -columnAlign 3 "center" -columnAttach 3 "both" 0 LUMBERYARDANIMATIONMANAGER_ADDITEM_ROW;
    {
        text -height $g_controlHeight -label "";
        text -height $g_controlHeight -label "";
        button -height $g_controlHeight -backgroundColor $g_UIColor[0] $g_UIColor[1] $g_UIColor[2] -label "+" -command ("LumberyardAnimationManagerAddNewItem");
    }
}

//! Rebuilds the animation export list in the Animation Manager based on the current state of the data backend
/*!
 \todo 
  Move the querying of children of LUMBERYARD_ANIMATIONEXPORT_GROUP to LumberyardUtilities for proper data/UI
  separation.
*/
global proc LumberyardAnimationManagerReadExports()
{
    global string $g_lastRow;
    $g_lastRow = "";
    
    string $children[] = `columnLayout -query -childArray LUMBERYARDANIMATIONMANAGER_EXPORT_SCROLLLAYOUT`;
    for ($child in $children)
    {
        deleteUI $child;
    }

    if(!`objExists "LUMBERYARD_ANIMATIONEXPORT_GROUP"`)
    {
        return;
    }
    
    string $exportNodes[] = `listRelatives -children "LUMBERYARD_ANIMATIONEXPORT_GROUP"`;
    
    for($exportNode in $exportNodes)
    {
        LumberyardAnimationManagerCreateUIRow($exportNode);
    }
    
    LumberyardAnimationManagerUpdateHeight();
    LumberyardAnimationManagerUpdateLastRow();
}

//! Creates the Animation Manager window and calls the necessary functions to populate it.
global proc LumberyardAnimationManagerCreateWindow()
{
    if(!`window -exists LUMBERYARDANIMATIONMANAGER_WINDOW`) 
    {
        if(`windowPref -exists LUMBERYARDANIMATIONMANAGER_WINDOW`) 
        {
            windowPref -widthHeight 905 65
                -topLeftCorner `windowPref -query -topEdge LUMBERYARDANIMATIONMANAGER_WINDOW` `windowPref -query -leftEdge LUMBERYARDANIMATIONMANAGER_WINDOW` LUMBERYARDANIMATIONMANAGER_WINDOW;
        }
        //Picked 900 so that the Animation Manager UI is long enough to fit the information for a typical 1920 x 1080 monitor. For 4K, the user can stretch the UI.
        window -titleBar true -title "Lumberyard Animation Manager" -widthHeight 905 65
            -sizeable true -minimizeButton false -maximizeButton false LUMBERYARDANIMATIONMANAGER_WINDOW;
        
        columnLayout -adjustableColumn true -height 65 -backgroundColor 0.26 0.26 0.26 LUMBERYARDANIMATIONMANAGER_MAINLAYOUT;
        {
            // Title Bar
            LumberyardAnimationManagerCreateColumnTitles();
            setParent LUMBERYARDANIMATIONMANAGER_MAINLAYOUT;
            columnLayout -height 1 -backgroundColor 0.26 0.26 0.26 LUMBERYARDANIMATIONMANAGER_EXPORT_SCROLLLAYOUT;
            setParent LUMBERYARDANIMATIONMANAGER_MAINLAYOUT;
            LumberyardAnimationManagerCreateAddButton();
        }
    }

    scriptJob -event "NewSceneOpened" "LumberyardAnimationManagerReadExports" -parent "LUMBERYARDANIMATIONMANAGER_WINDOW";
    scriptJob -event "PostSceneRead" "LumberyardAnimationManagerReadExports" -parent "LUMBERYARDANIMATIONMANAGER_WINDOW";
    scriptJob -event "animLayerRebuild" "LumberyardAnimationManagerUpdateLayers" -parent "LUMBERYARDANIMATIONMANAGER_WINDOW";
    
    LumberyardUtilitiesUpdateAnimationLayers();
    LumberyardAnimationManagerReadExports();
    
    showWindow LUMBERYARDANIMATIONMANAGER_WINDOW;
}