/*
 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:   Package.cpp
 * Author: alain
 *
 * Created on March 18, 2018, 7:58 PM
 */
#include "../SourceCompile/SymbolTable.h"
#include "../Expression/ExprBuilder.h"
#include "Package.h"
#include "../Testbench/ClassDefinition.h"

using namespace SURELOG;

Package::~Package() {}

unsigned int Package::getSize() {
  NodeId end = this->m_nodeIds[0];
  NodeId begin = m_fileContents[0]->Child(end);
  unsigned int size = end - begin;
  return size;
}

ClassDefinition* Package::getClassDefinition(const std::string& name) {
  ClassNameClassDefinitionMultiMap::iterator itr =
      m_classDefinitions.find(name);
  if (itr == m_classDefinitions.end()) {
    return NULL;
  } else {
    return (*itr).second;
  }
}
void Package::append(Package* package) {
  DesignComponent::append(package);
  for (auto& type : package->m_dataTypes)
    insertDataType(type.first, type.second);
  for (auto& param : package->getMappedValues())
    setValue(param.first, param.second, m_exprBuilder);
  for (auto& classDef : package->m_classDefinitions) {
    addClassDefinition(classDef.first, classDef.second);
    classDef.second->setContainer(this);
  }
}
