/*
 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:   ModuleDefinition.h
 * Author: alain
 *
 * Created on October 20, 2017, 10:29 PM
 */

#ifndef MODULEDEFINITION_H
#define MODULEDEFINITION_H
#include <vector>
#include "DesignComponent.h"
#include "ValuedComponentI.h"
#include "Signal.h"
#include "ClockingBlock.h"
#include "DataType.h"
#include "../Common/ClockingBlockHolder.h"

namespace SURELOG {
class CompileModule;

class ModuleDefinition : public DesignComponent, public ClockingBlockHolder {
    friend CompileModule;
public:  
    ModuleDefinition(FileContent* fileContent, NodeId nodeId, std::string& name);
  
    virtual ~ModuleDefinition();
 
    std::string  getName() { return m_name; }
    VObjectType  getType() { return (m_fileContents.size()) ? m_fileContents[0]->Type(m_nodeIds[0]) : VObjectType::slN_input_gate_instance; }
    bool         isInstance();    
    unsigned int getSize();
    
    typedef  std::map<SymbolId, ClockingBlock>       ClockingBlockMap;
    typedef  std::map<SymbolId, std::vector<Signal>> ModPortSignalMap;    
    typedef  std::map<SymbolId, std::vector<ClockingBlock>> ModPortClockingBlockMap;
    
    ModPortSignalMap& getModPortSignalMap() { return m_modportSignalMap; }
    ModPortClockingBlockMap& getModPortClockingBlockMap() { return m_modportClockingBlockMap; }
    void insertModPort(SymbolId modport, Signal& signal);
    void insertModPort(SymbolId modport, ClockingBlock& block);
    Signal* getModPortSignal(SymbolId modport, NodeId port);
    ClockingBlock* getModPortClockingBlock(SymbolId modport, NodeId port);   
    
    ClassNameClassDefinitionMultiMap& getClassDefinitions() { return m_classDefinitions; }
    void addClassDefinition(std::string className, ClassDefinition* classDef) { m_classDefinitions.insert(std::make_pair(className, classDef)); }
    ClassDefinition* getClassDefinition(const std::string& name); 
    
    std::vector<Signal>&   getPorts() { return m_ports; }
    std::vector<Signal>&   getSignals() { return m_signals; }
    
private:   
    std::string  m_name;
    std::vector<Signal>     m_ports;
    std::vector<Signal>     m_signals;
    ModPortSignalMap        m_modportSignalMap; 
    ModPortClockingBlockMap m_modportClockingBlockMap;
    ClassNameClassDefinitionMultiMap m_classDefinitions;
};



class ModuleDefinitionFactory {
    public:
        ModuleDefinition* newModuleDefinition(FileContent* fileContent, 
                                              NodeId nodeId, 
                                              std::string name); 
        
};


};

#endif /* MODULEDEFINITION_H */


