/*
 Do not modify, auto-generated by classes.py

 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:   ports.h
 * Author:
 *
 * Created on December 14, 2019, 10:03 PM
 */

#ifndef UHDM_PORTS_H
#define UHDM_PORTS_H

#include <uhdm/sv_vpi_user.h>
#include <uhdm/uhdm_vpi_user.h>

#include <uhdm/containers.h>
#include <uhdm/BaseClass.h>

#include "expr_ref_obj_group.h"


namespace UHDM {
class instance;
class module_inst;
class ref_typespec;

class ports : public BaseClass {
  UHDM_IMPLEMENT_RTTI(ports, BaseClass)
public:
  // Implicit constructor used to initialize all members,
  // comment: ports();
  virtual ~ports() = default;

  int32_t VpiPortIndex() const { return vpiPortIndex_; }
  bool VpiPortIndex(int32_t data) {
    vpiPortIndex_ = data;
    return true;
  }

  virtual bool VpiName(std::string_view data) final;
  virtual std::string_view VpiName() const final;

  int32_t VpiPortType() const { return vpiPortType_; }
  bool VpiPortType(int32_t data) {
    vpiPortType_ = data;
    return true;
  }

  bool VpiScalar() const { return vpiScalar_; }
  bool VpiScalar(bool data) {
    vpiScalar_ = data;
    return true;
  }

  bool VpiVector() const { return vpiVector_; }
  bool VpiVector(bool data) {
    vpiVector_ = data;
    return true;
  }

  bool VpiConnByName() const { return vpiConnByName_; }
  bool VpiConnByName(bool data) {
    vpiConnByName_ = data;
    return true;
  }

  int32_t VpiDirection() const { return vpiDirection_; }
  bool VpiDirection(int32_t data) {
    vpiDirection_ = data;
    return true;
  }

  int32_t VpiSize() const { return vpiSize_; }
  bool VpiSize(int32_t data) {
    vpiSize_ = data;
    return true;
  }

  bool VpiExplicitName(std::string_view data);
  std::string_view VpiExplicitName() const;

  any* High_conn()  { return high_conn_; }
  const any* High_conn() const { return high_conn_; }
  template <typename T>
  T* High_conn() {
    return (high_conn_ == nullptr) ? nullptr : any_cast<T*>(high_conn_);
  }
  template <typename T>
  const T* High_conn() const {
    return (high_conn_ == nullptr) ? nullptr : any_cast<const T*>(high_conn_);
  }
  bool High_conn(any* data) {
    if (!expr_ref_obj_groupGroupCompliant(data)) return false;
    high_conn_ = data;
    return true;
  }

  any* Low_conn()  { return low_conn_; }
  const any* Low_conn() const { return low_conn_; }
  template <typename T>
  T* Low_conn() {
    return (low_conn_ == nullptr) ? nullptr : any_cast<T*>(low_conn_);
  }
  template <typename T>
  const T* Low_conn() const {
    return (low_conn_ == nullptr) ? nullptr : any_cast<const T*>(low_conn_);
  }
  bool Low_conn(any* data) {
    if (!expr_ref_obj_groupGroupCompliant(data)) return false;
    low_conn_ = data;
    return true;
  }

  ref_typespec* Typespec()  { return typespec_; }
  const ref_typespec* Typespec() const { return typespec_; }
  template <typename T>
  T* Typespec() {
    return (typespec_ == nullptr) ? nullptr : any_cast<T*>(typespec_);
  }
  template <typename T>
  const T* Typespec() const {
    return (typespec_ == nullptr) ? nullptr : any_cast<const T*>(typespec_);
  }
  bool Typespec(ref_typespec* data) {
    typespec_ = data;
    return true;
  }

  instance* Instance()  { return instance_; }
  const instance* Instance() const { return instance_; }
  template <typename T>
  T* Instance() {
    return (instance_ == nullptr) ? nullptr : any_cast<T*>(instance_);
  }
  template <typename T>
  const T* Instance() const {
    return (instance_ == nullptr) ? nullptr : any_cast<const T*>(instance_);
  }
  bool Instance(instance* data) {
    instance_ = data;
    return true;
  }

  module_inst* Module_inst()  { return module_inst_; }
  const module_inst* Module_inst() const { return module_inst_; }
  template <typename T>
  T* Module_inst() {
    return (module_inst_ == nullptr) ? nullptr : any_cast<T*>(module_inst_);
  }
  template <typename T>
  const T* Module_inst() const {
    return (module_inst_ == nullptr) ? nullptr : any_cast<const T*>(module_inst_);
  }
  bool Module_inst(module_inst* data) {
    module_inst_ = data;
    return true;
  }

  virtual ports* DeepClone(BaseClass* parent, CloneContext* context) const override = 0;

  virtual const BaseClass* GetByVpiName(std::string_view name) const override;

  virtual std::tuple<const BaseClass*, UHDM_OBJECT_TYPE, const std::vector<const BaseClass*>*> GetByVpiType(int32_t type) const override;

  virtual vpi_property_value_t GetVpiPropertyValue(int32_t property) const override;

  virtual int32_t Compare(const BaseClass* other, CompareContext* context) const override;

  virtual  UHDM_OBJECT_TYPE UhdmType() const override { return UHDM_OBJECT_TYPE::uhdmports; }

protected:
  void DeepCopy(ports* clone, BaseClass* parent, CloneContext* context) const;

private:
  int32_t vpiPortIndex_ = 0;

  SymbolId vpiName_;

  int32_t vpiPortType_ = 0;

  bool vpiScalar_ = false;

  bool vpiVector_ = false;

  bool vpiConnByName_ = false;

  int32_t vpiDirection_ = 0;

  int32_t vpiSize_ = 0;

  SymbolId vpiExplicitName_;

  any* high_conn_ = nullptr;

  any* low_conn_ = nullptr;

  ref_typespec* typespec_ = nullptr;

  instance* instance_ = nullptr;

  module_inst* module_inst_ = nullptr;
};

#if 0 // This class cannot be instantiated
typedef FactoryT<ports> portsFactory;
#endif

typedef FactoryT<std::vector<ports *>> VectorOfportsFactory;

}  // namespace UHDM

#endif
