#include "vhdl_err.h"
#include "vhdl_parser_struct.h"
#include "../named.h"
#include <sstream>

using namespace std;
using namespace hub;
//------------------------------------------------------------------------------------
vector<StringToken> InterfaceDecl::GeneratePortNames(){
	vector<StringToken> names;
 if(dynamic_cast<SimpleType*>(type)) names.push_back(portName);
	// generating names of bits in array type
 ArrayType* arr_type = dynamic_cast<ArrayType*>(type);
 if(arr_type){
		RangeAssocElem* range  = dynamic_cast<RangeAssocElem*>(arr_type);
		StringToken name(portName);
		name.augment(0);
		for(GenAssocList::iterator i = arr_type->list.begin(); i!=arr_type->list.end();++i){
			range = dynamic_cast<RangeAssocElem*>(*i);
			if(range)
				for(int j = 0; j < range->Range(); j++) {
					names.push_back(name);
					name.nextAugment();	
				}
		}
  }
  return names;
}
//------------------------------------------------------------------------------------
bool RangeAssocElem::validate(){
	//validating range
	switch( direction ){
		case D_TO:
			if( left > right ) return false;
			break;
		case D_DOWNTO:
			if(left < right ) return false;
	}
	return true;
}
//------------------------------------------------------------------------------------
int RangeAssocElem::Range(){
	// calculating range
	switch( direction ){
		case D_TO:
			return (right - left  + 1);
		case D_DOWNTO:
			return (left - right + 1 );
		default:
			return 0;
	}
}
//------------------------------------------------------------------------------------

StringToken IndexName::GenerateName(void){
	//Generating indexed name
	 std::ostringstream name;
	  name << mark_;
	for(GenAssocList::iterator i = indexes_->begin(); i!=indexes_->end(); ++i ){
      NamedAssocElem* n = dynamic_cast<NamedAssocElem*>(*i);
	  if(!n || n->formal_ ) {
		throw VhdlOthException( OthReason("Error in indexed name","",""),
		VhdlFilePosition(mark_),CircCtx());
	  }
      LiteralExpr* lit = dynamic_cast<LiteralExpr*>(n->actual_);
      if(!lit){
		  throw VhdlOthException( OthReason("Indexed name:"," Index must be a number",""),
		VhdlFilePosition(mark_),CircCtx());
	  }
	  name << "_" << lit->Val();
    }
	return StringToken(name.str(),mark_.Location());
}
//------------------------------------------------------------------------------------
