
Eag_branch::Eag_branch(tag tid) 
{
  id = tid;
  dV = 0; I = 0; Qheat = 0;
  links.clear();
  NodeNo[Pminus] = -1; NodeNo[Pplus] = -1;
  if (id < 0) return; // not ready for the rest yet
  info = new (dc_data[dc_agent_circuit::NCInfo]); // OK?
  branch = query_branch( id, info ); // OK?
  bool badBranch = false;
  switch (branch)
    {
    case Resistor: if ( !(info[Res]) ) badBranch = true; break;
    case Capacitor: if ( !(info[Cap]) ) badBranch = true; break;
    case Inductor: if ( !(info[Ind]) ) badBranch = true; break;
    case Transistor: if ( !(info[Imax]) !(info[Nu]) ) badBranch = true; 
      break;
    case Amp: if ( !(info[Imax]) !(info[Nu]) ) badBranch = true; break;
    case Motor: if ( !(info[kI]) || !(info[kV]) || !(info[IMax]) || !(info[Nu]) )
      badBranch = true;  break;
    case Switch: if ( !(info[On]) ) badBranch = true; break;
    case Dcdc: if ( !(info[Imax]) ) badBranch = true; break;
    case Battery: if ( !(info[Res]) !(info[Vc]) ) badBranch = true; break;
    case Custom: if ( !(info[Y]) || !(info[Ig]) ) badBranch = true; break;
      
    CT_Undef:
    default:
      cerr << "Eag_branch::Eag_branch, branch with tag : "<< id << 
	" has bad branch type : " << branch << "\n";
      return;
    }
  if (BadBranch) cerr<< "Eag_branch::Eag_branch insufficient or bad info for element tag :" 
    << id << ", branch type : " << dc_agent_circuit::circ_type_name[branch];
  return;
}

Eag_branch::Eag_branch(void) 
{
  Eag_branch(-1);
}

Eag_branch::~Eag_branch()
{
  id = -1;
  for(int i = 0, i <  dc_agent_circuit::NCInfo, i++) 
    {delete info[i]; info[i] = nil;} // delete calls the destructors
  delete info;

  dic_item di;
  forall_items(di, links) {
    delete links.inf(di);
    links.del_item(di);
  }
  NodeNo[Pminus] = -1; NodeNo[Pplus] = -1;
  dV = 0; I = 0; Qheat = 0;
}

void tagError(string &s, tag tid)
{
  cerr << "Error in Eag_branch::" << s << "; branch tag : " << id << 
      ", does not match reference external tag : " << tid <<"\n";
  return;
}

bool Eag_branch::badTag(tag tid)
{
  bool notOK = (tid != id);
  if (notOK)
    tagError("check", tid);
  return notOK;
}

bool Eag_branch::addLink(tag tid, plus_type plus, tag t, plus_type tPlus, Eag_branch *tbranch, 
			 bool *newNode)
{
  if (badTag(tid)) 
    {tagError("addLink", tid); return true;}

  if (links.lookup(t))
    {cerr << "Error Eag_branch::addLink, added tag : " << t << 
       "already exists in the branch dictionary of tag : " << id << "\n";
     return true;}
     
  *newNode = false;

  LinkStruct *L = new LinkStruct;
  L->plus = plus;
  L->destplus = tplus;
  links.insert(t, L);
  
  // attach node if exists, else instantiate new node
  if (NodeNo[plus] < 0) 
    {
      if ((NodeNo[plus] = tbranch->node(tplus)) < 0)
	{NodeNo[plus] = NNodes+1;
	 *newNode = true;}
    }
  return false;
}

bool Eag_branch::delLink(tag tid, tag t)
{
  if (badTag(tid)) 
    {tagError("delLink", tid); return true;}
  dic_item di = nil;
  if (!(item = links.lookup(t)))
    {cerr << "Eag_branch::delLink link from tag : " << id << "to tag :" << t <<
       "not found \n";
     return true;}

  delete links.inf(di);
  links.del_item(di);
  return false;
}

bool Eag_branch::getproperties(tag tid, double *Y, double *Ig)
{
  if (badTag(tid)) 
    {tagError("properties", tid); return true;}
  switch (branch)
    {
    case Resistor: *Y = 1.0/( ((dc_real *)info[Res])->get_mag() );
      *Ig = 0.0; break;
    case Capacitor: break;
    case Inductor: break;
    case Transistor: break;
    case Amp: break;
    case Motor: break;
    case Switch: break;
    case Dcdc: break;
    case Custom: break;
      
    CT_Undef:
    default:
      cerr << "Eag_branch::getproperties, branch with tag : "<< id << 
	" has bad branch type : " << branch << "\n";
      return true;
      
    }
  return false;
}

bool Eag_branch::set(tag tid, double tdV, double tI, double tQheat)
{
  if (badTag(tid)) 
    {tagError("set", tid); return true;}
  dV = tdV; I = tI; Qheat = tQheat;
  return false;
}

bool Eag_branch::get(tag tid, double *dV, double *I, double *Qheat)
{
  if (badTag(tid)) 
    {tagError("get", tid); return true;}
  *dV = this->dV; *I = this->I; *Qheat = this->Qheat;
  return false;
}
