/*
 Copyright 2019 Alain Dargelas
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
 
 http://www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

/* 
 * File:   ModuleInstance.h
 * Author: alain
 *
 * Created on October 16, 2017, 10:48 PM
 */

#ifndef MODULEINSTANCE_H
#define MODULEINSTANCE_H

#include "ModuleDefinition.h"
#include "../Expression/Value.h"
#include "../Expression/ExprBuilder.h"
#include "ValuedComponentI.h"

namespace SURELOG {


class ModuleInstance : public ValuedComponentI {
public:
    ModuleInstance(DesignComponent* definition, FileContent* fileContent, NodeId nodeId, ModuleInstance* parent, 
                   std::string instName, std::string moduleName);
    virtual ~ModuleInstance();
    void addSubInstances(ModuleInstance** subInstances, unsigned int nbSubInstances);
    DesignComponent*  getDefinition()  { return m_definition; }
    unsigned int      getNbChildren()  { return m_nbChildren; }
    ModuleInstance*   getChildren(unsigned int i) { return m_childrens[i]; }
    ModuleInstance*   getParent()      { return m_parent; } 
    FileContent*      getFileContent() { return m_fileContent; } 
    SymbolId          getFileId()      { return m_fileContent->getFileId(m_nodeId); } 
    std::string       getFileName()    { return m_fileContent->getFileName(m_nodeId); }
    NodeId            getNodeId()      { return m_nodeId; }
    unsigned int      getLineNb();
    VObjectType       getType();
    VObjectType       getModuleType();
    SymbolId          getFullPathId(SymbolTable* symbols);
    SymbolId          getInstanceId(SymbolTable* symbols);
    SymbolId          getModuleNameId(SymbolTable* symbols);
    std::string       getInstanceName();
    std::string       getFullPathName();
    std::string       getModuleName();
    unsigned int      getDepth();
 
    void              setNodeId(NodeId id) { m_nodeId = id; } // Used for generate stmt
    void              overrideParentChild(ModuleInstance* parent, ModuleInstance* interm, ModuleInstance* child);
private:
    DesignComponent* m_definition;
    ModuleInstance**  m_childrens;
    unsigned int      m_nbChildren;
    FileContent*      m_fileContent; 
    NodeId            m_nodeId;
    ModuleInstance*   m_parent;
    std::string       m_instName; // Can carry the moduleName@instanceName if the module is undefined
    std::map<std::string, Value*> m_paramMap;
    
};


class ModuleInstanceFactory {
    public:
        ModuleInstance* newModuleInstance(DesignComponent* definition, FileContent* fileContent, NodeId nodeId, ModuleInstance* parent, 
                                          std::string instName, std::string moduleName); 
        
};

};

#endif /* MODULEINSTANCE_H */


