/* Copyright (C) 2019-2020 Stephan Kreutzer
 *
 * This file is part of dimgra-1.
 *
 * dimgra-1 is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 or any later
 * version of the license, as published by the Free Software Foundation.
 *
 * dimgra-1 is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License 3 for more details.
 *
 * You should have received a copy of the GNU Affero General Public License 3
 * along with dimgra-1. If not, see <http://www.gnu.org/licenses/>.
 */

"use strict";

let currentNode = null;
let currentXAxisDimension = null;
let currentYAxisDimension = null;
let graphEngine = new GraphEngine();

// TODO: This should be optimized by caching xParents and xChildren
// that were already loaded/interpreted for the current node.

function NavigateNode(nodeId, dimensionalPivot)
{
    currentNode = null;

    ResetDetails();
    Reset();

    let node = graphEngine.getNodeById(nodeId);

    if (node == null)
    {
        throw "Loading a node failed.";
    }

    if (dimensionalPivot == true)
    {
        currentYAxisDimension = currentXAxisDimension;
        currentXAxisDimension = null;
    }
    else
    {
        let found = false;

        for (let i = 0; i < node.getChildren().length; i++)
        {
            let dimension = node.getChildren()[i].getDimension();

            if (dimension === null)
            {
                dimension = "";
            }

            if (currentYAxisDimension !== null)
            {
                if (dimension === currentYAxisDimension)
                {
                    continue;
                }
            }

            if (dimension === currentXAxisDimension)
            {
                found = true;
                break;
            }
        }

        if (found === false)
        {
            currentXAxisDimension = null;
        }
    }

    if (currentYAxisDimension === null)
    {
        for (let i = 0; i < node.getParents().length; i++)
        {
            if (node.getParents()[i].isDimensionEstablishing() === true)
            {
                currentYAxisDimension = node.getParents()[i].getDimension();

                if (currentYAxisDimension === null)
                {
                    currentYAxisDimension = "";
                }

                break;
            }
        }

        if (currentYAxisDimension === null)
        {
            for (let i = 0; i < node.getChildren().length; i++)
            {
                if (node.getChildren()[i].isDimensionEstablishing() === true)
                {
                    currentYAxisDimension = node.getChildren()[i].getDimension();

                    if (currentYAxisDimension === null)
                    {
                        currentYAxisDimension = "";
                    }

                    break;
                }
            }
        }

        if (currentYAxisDimension === null)
        {
            // No prior knowledge about dimensions pointing inwards.
            currentYAxisDimension = "";
        }
    }

    if (currentXAxisDimension === null)
    {
        for (let i = 0; i < node.getChildren().length; i++)
        {
            if (currentYAxisDimension !== null)
            {
                if (node.getChildren()[i].getDimension() === currentYAxisDimension)
                {
                    continue;
                }
            }

            currentXAxisDimension = node.getChildren()[i].getDimension();

            if (currentXAxisDimension === null)
            {
                currentXAxisDimension = "";
            }

            break;
        }
    }


    let xChildren = new Array();
    let yChildren = new Array();
    let xDimensions = new Array();

    for (let i = 0; i < node.getChildren().length; i++)
    {
        let dimension = node.getChildren()[i].getDimension();

        if (dimension === null)
        {
            dimension = "";
        }

        if (currentYAxisDimension !== null)
        {
            if (dimension === currentYAxisDimension)
            {
                if (yChildren.length > 1)
                {
                    console.log("y-axis with more than one child.");
                    continue;
                }

                yChildren.push(graphEngine.getNodeById(node.getChildren()[i].getId()));
                continue;
            }
        }

        if (currentXAxisDimension !== null)
        {
            if (dimension === currentXAxisDimension)
            {
                xChildren.push(graphEngine.getNodeById(node.getChildren()[i].getId()));
            }
        }

        if (xDimensions.includes(node.getChildren()[i].getDimension()) != true)
        {
            xDimensions.push(node.getChildren()[i].getDimension());
        }
    }


    {
        let before = null;
        let after = null;

        if (yChildren.length > 0)
        {
            after = yChildren[0];
        }

        for (let i = 0; i < node.getParents().length; i++)
        {
            if (node.getParents()[i].isDimensionEstablishing() === true)
            {
                if (node.getParents()[i].getDimension() === currentYAxisDimension)
                {
                    before = graphEngine.getNodeById(node.getParents()[i].getId());
                    break;
                }
            }
        }

        if (RenderYAxis(before, node, after, currentYAxisDimension) == true)
        {
            currentNode = node.getId();
        }
        else
        {
            return false;
        }
    }



    if (UpdateDimensions(xDimensions, "axis-x-dimension", currentXAxisDimension) != true)
    {
        return false;
    }

    if (RenderXChildren(xChildren, currentXAxisDimension) != true)
    {
        return false;
    }

    if (UpdateDimensions(new Array(currentYAxisDimension), "axis-y-dimension", currentYAxisDimension) != true)
    {
        return false;
    }

    return true;
}

function ShowDetails(nodeId)
{
    ResetDetails();

    let node = graphEngine.getNodeById(nodeId);

    if (node == null)
    {
        throw "Loading a node failed.";
    }

    if (RenderDetails(node) != 0)
    {
        return -1;
    }

    return 0;
}

function ChangeAxisDimension(axis)
{
    if (axis == "x")
    {
        let axisControl = document.getElementById("axis-x-dimension");

        if (axisControl == null)
        {

        }

        currentXAxisDimension = axisControl.options[axisControl.selectedIndex].value
    }
    else if (axis == "y")
    {
        let axisControl = document.getElementById("axis-y-dimension");

        if (axisControl == null)
        {

        }

        currentYAxisDimension = axisControl.options[axisControl.selectedIndex].value
    }
    else
    {
        throw "Unknown axis '" + axis + "'.";
    }

    NavigateNode(currentNode, false);
}
