#ifndef TOTALS_CPP
#define TOTALS_CPP

#include "totals.h"

vector<string> Totals::partners;

Totals::Totals(){
  if(partners.size()==0)throw new NoPartnersError;
  upmass=0;
  crewtrng=0;
  middecks=0;
  stowage=0;
  keepalive=0;
  MTL=0;
  acoustics=0;
  energy=0;
  crewtime=0;
  count=0;

  vector<double> temp;
  temp.reserve(partners.size());
  for(int n=0;n!=partners.size();n++)
    temp.push_back(0.0);

  upmass_partners=temp;
  crewtrng_partners=temp;
  middecks_partners=temp;
  stowage_partners=temp;
  keepalive_partners=temp;
  MTL_partners=temp;
  acoustics_partners=temp;
  energy_partners=temp;
  crewtime_partners=temp;
  count_partners=temp;
}

Totals::~Totals(){}


void Totals::addRack(Rack rack){
  if(partners.size()==0)throw new NoPartnersError;
  upmass+=rack.upmass_resupply*(rack.rack_overhead+1)+rack.mid_resupply*rack.middeckmass;
  if(!rack.attached)acoustics+=rack.calc_runtime(); // FIXME (this is used for acoustics, acoustics shouldn't be a straight count of racks)
  count+=1;
  crewtrng+=rack.crew_training;
  middecks+=rack.mid_resupply;
  stowage+=rack.stowage;
  keepalive+=rack.keepalive_power;
  MTL+=rack.calc_MTL_flow()*rack.calc_runtime()+rack.calc_MTL_flow_keepalive()*(rack.inclength*24-rack.calc_runtime());
  energy+=rack.calc_energy();
  crewtime+=rack.crew_time;

  bool added=false;
  for(int n=0;n!=partners.size();n++)
    if(rack.partner==partners[n])
      {
	added=true;
	upmass_partners[n]+=rack.upmass_resupply*(rack.rack_overhead+1)+rack.mid_resupply*rack.middeckmass;
	if(!rack.attached)acoustics_partners[n]+=rack.calc_runtime(); // FIXME (this is used for acoustics, acoustics shouldn't be a straight count of racks)
	count_partners[n]+=1;
	crewtrng_partners[n]+=rack.crew_training;
	middecks_partners[n]+=rack.mid_resupply;
	stowage_partners[n]+=rack.stowage;
	keepalive_partners[n]+=rack.keepalive_power;
	MTL_partners[n]+=rack.calc_MTL_flow()*rack.calc_runtime()+rack.calc_MTL_flow_keepalive()*(rack.inclength*24-rack.calc_runtime());
	energy_partners[n]+=rack.calc_energy();
	crewtime_partners[n]+=rack.crew_time;
	break;
      }
  if(!added)throw new BadPartnerError(rack.partner);
}
 
void Totals::addTotals(Totals totals){
  if(partners.size()==0)throw new NoPartnersError;
  upmass+=totals.upmass;
  crewtrng+=totals.crewtrng;
  middecks+=totals.middecks;
  stowage+=totals.stowage;
  keepalive+=totals.keepalive;
  MTL+=totals.MTL;
  acoustics+=totals.acoustics;
  energy+=totals.energy;
  crewtime+=totals.crewtime;  
  count+=totals.count;

  for(int n=0;n!=partners.size();n++)
    {
      count_partners[n]+=totals.count_partners[n];
      upmass_partners[n]+=totals.upmass_partners[n];
      crewtrng_partners[n]+=totals.crewtrng_partners[n];
      middecks_partners[n]+=totals.middecks_partners[n];
      stowage_partners[n]+=totals.stowage_partners[n];
      keepalive_partners[n]+=totals.keepalive_partners[n];
      MTL_partners[n]+=totals.MTL_partners[n];
      acoustics_partners[n]+=totals.acoustics_partners[n];
      energy_partners[n]+=totals.energy_partners[n];
      crewtime_partners[n]+=totals.crewtime_partners[n];
    }
}

Totals Totals::operator + (const Totals& totals) const{
  Totals temp=*this;
  temp.addTotals(totals);
  return temp;
}


Totals Totals::operator + (const Rack& rack) const{
  Totals temp=*this;
  temp.addRack(rack);
  return temp;
}

Totals Totals::operator += (const Totals& totals){
  addTotals(totals);
  return *this;
}


Totals Totals::operator += (const Rack& rack){
  addRack(rack);
  return *this;
}
 #endif
