//
// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#include "compiler/translator/InitializeVariables.h"
#include "compiler/translator/compilerdebug.h"

namespace
{

TIntermConstantUnion *constructFloatConstUnionNode(const TType &type)
{
    TType myType = type;
    unsigned char size = myType.getNominalSize();
    if (myType.isMatrix())
        size *= size;
    ConstantUnion *u = new ConstantUnion[size];
    for (int ii = 0; ii < size; ++ii)
        u[ii].setFConst(0.0f);

    myType.clearArrayness();
    myType.setQualifier(EvqConst);
    TIntermConstantUnion *node = new TIntermConstantUnion(u, myType);
    return node;
}

TIntermConstantUnion *constructIndexNode(int index)
{
    ConstantUnion *u = new ConstantUnion[1];
    u[0].setIConst(index);

    TType type(EbtInt, EbpUndefined, EvqConst, 1);
    TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
    return node;
}

}  // namespace anonymous

bool InitializeVariables::visitAggregate(Visit visit, TIntermAggregate *node)
{
    bool visitChildren = !mCodeInserted;
    switch (node->getOp())
    {
      case EOpSequence:
        break;
      case EOpFunction:
      {
        // Function definition.
        ASSERT(visit == PreVisit);
        if (node->getName() == "main(")
        {
            TIntermSequence *sequence = node->getSequence();
            ASSERT((sequence->size() == 1) || (sequence->size() == 2));
            TIntermAggregate *body = NULL;
            if (sequence->size() == 1)
            {
                body = new TIntermAggregate(EOpSequence);
                sequence->push_back(body);
            }
            else
            {
                body = (*sequence)[1]->getAsAggregate();
            }
            ASSERT(body);
            insertInitCode(body->getSequence());
            mCodeInserted = true;
        }
        break;
      }
      default:
        visitChildren = false;
        break;
    }
    return visitChildren;
}

void InitializeVariables::insertInitCode(TIntermSequence *sequence)
{
    for (size_t ii = 0; ii < mVariables.size(); ++ii)
    {
        const InitVariableInfo &varInfo = mVariables[ii];

        if (varInfo.type.isArray())
        {
            for (int index = varInfo.type.getArraySize() - 1; index >= 0; --index)
            {
                TIntermBinary *assign = new TIntermBinary(EOpAssign);
                sequence->insert(sequence->begin(), assign);

                TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect);
                TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type);
                indexDirect->setLeft(symbol);
                TIntermConstantUnion *indexNode = constructIndexNode(index);
                indexDirect->setRight(indexNode);

                assign->setLeft(indexDirect);

                TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type);
                assign->setRight(zeroConst);
            }
        }
        else
        {
            TIntermBinary *assign = new TIntermBinary(EOpAssign);
            sequence->insert(sequence->begin(), assign);
            TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type);
            assign->setLeft(symbol);
            TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type);
            assign->setRight(zeroConst);
        }

    }
}

