/**************************************************************
 * FFTacticsMUD : status.cpp                                  *
 **************************************************************
 * (c) 2002 Damien Dailidenas (Trenton). All rights reserved. *
 **************************************************************/

#include "main.h"
#include <strstream>

const struct status_type status_table[] = {
    { "Charging",       0,      status_charging         },
    { "Defending",      0,      status_defending        },
    { "Performing",     0,      status_performing       },

    { "Accumulate",     0,      status_accumulate       },
    { "Berserk",        0,      status_berserk          },
    { "Blood Suck",     0,      status_bloodsuck        },
    { "Charm",          31,     status_charm            },
    { "Confusion",      0,      status_confusion        },
    { "Darkness",       0,      status_darkness         },
    { "Death Sentence", 0,      status_deathsentence    },
    { "Dead",           0,      status_dead             },
    { "Don't Act",      23,     status_dontact          },
    { "Don't Move",     23,     status_dontmove         },
    { "Faith",          31,     status_faith            },
    { "Float",          0,      status_float            },
    { "Frog",           0,      status_frog             },
    { "Haste",          31,     status_haste            },
    { "Innocent",       31,     status_innocent         },
    { "Invitation",     0,      status_invitation       },
    { "Oil",            0,      status_oil              },
    { "Petrify",        0,      status_petrify          },
    { "Poison",         35,     status_poison           },
    { "Protect",        31,     status_protect          },
    { "Reflect",        31,     status_reflect          },
    { "Regen",          35,     status_regen            },
    { "Reraise",        0,      status_reraise          },
    { "Shell",          31,     status_shell            },
    { "Silence",        0,      status_silence          },
    { "Slow",           23,     status_slow             },
    { "Sleep",          59,     status_sleep            },
    { "Stop",           19,     status_stop             },
    { "Transparent",    0,      status_transparent      },
    { "Undead",         0,      status_undead           },
    {}
};

STATUS *CH::add(STATUSTYPE *status_type, const short ctr=0, const short chance=0, const bool announce=true) {
  STATUS *status;
    
  if(chance && num_percent() > chance)
    return false;
    
  status = new STATUS;
  status->next = this->status_list;
  this->status_list = status;
  status->type = status_type;
  status->id = get_status_id(status_type);
  status->ctr = ctr;
  status_type(this, status, STATUS_ADD);

  if(announce)
    battle->echo(name + " has been affected by \"" + status->name() + "\"!\n\r");
    
  return status;
}
    
void CH::clear_status(const bool announce = true) {
  for(STATUS *status = status_list, *status_next; status; status = status_next) {
    status_next = status->next;
    remove(status, announce);
  }
  
  return;
}

void CH::cancel(STATUSTYPE *type, const bool announce=true) {
  STATUS *status;

  while((status = this->status(type)))
    remove(status, announce);

  return;
}

void CH::remove(STATUS *status, const bool announce = true) {
  if(!status)
    return;

  if(announce)
    battle->echo(name + " is no longer affected by \"" + status->name() + "\".\n\r");

  if(status == status_list)
    status_list = status->next;
  else {
    for(STATUS *prev = status_list; prev; prev = prev->next) {
      if(prev->next == status) {
        prev->next = status->next;  
        break;
      }
    }
  }
  
  status->type(this, status, STATUS_REMOVE);
  zap(status);
  return;
}

void CH::status_update() {
  for(STATUS *status = status_list, *status_next = NULL; status; status = status_next) {
    status_next = status->next;
    status->type(this, status, STATUS_UPDATE);
  }

  return;
}

STATUS *CH::status(STATUSTYPE *type) {
  for(STATUS *status = status_list; status; status = status->next)
    if(status_table[status->id].type == type)
      return status;

  return NULL;
}

string STATUS::name() {
  return status_table[id].name;
}

short get_status_id(STATUSTYPE *type) {
  for(short x = 1; status_table[x].name; ++x)
    if(status_table[x].type == type)
      return x;

  return 0;
}

short get_status_id_by_name(const string name) {
  for(short x = 1; status_table[x].name; ++x)
    if(name == status_table[x].name)
      return x;

  return 0;
}

/********************
 * STATUS FUNCTIONS *
 ********************/
void status_charging(CH *ch, STATUS *status, const short action) {
  switch(action) {
  case STATUS_ADD:
    ch->printf("\"" + (string)skill_table[ch->action.id].name + "\" cancelled.\n\r");
    ch->cancel(status_charging, false);
    ch->action.action = NULL;
    ch->action.target = NULL;
    ch->action.id = 0;
    ch->action.ctr = 0;
    return;
  }
 
  return;
}
 
void status_defending(CH *ch, STATUS *status, const short action) {
}
 
void status_performing(CH *ch, STATUS *status, const short action) {
}
 
void status_accumulate(CH *ch, STATUS *status, const short action) {
  switch(action) {
  case STATUS_ADD:
    ++ch->PA;
    return;
  case STATUS_REMOVE:
    --ch->PA;
    return;
  }
    
  return;
}
      
void status_darkness(CH *ch, STATUS *status, const short action) {
}
   
void status_silence(CH *ch, STATUS *status, const short action) {
}
 
void status_berserk(CH *ch, STATUS *status, const short action) {
}
 
void status_bloodsuck(CH *ch, STATUS *status, const short action) {
}

void status_charm(CH *ch, STATUS *status, const short action) {
}
 
void status_confusion(CH *ch, STATUS *status, const short action) {
}
  
void status_dead(CH *ch, STATUS *status, const short action) {
  switch(action) {
  case STATUS_ADD:
    ch->HP[0] = 0;
    status->turns = 3;
    break;
  case STATUS_UPDATE:  
    if(!--status->turns)
      ch->die(NULL);
 
    break;
  }
 
  return;
}
 
void status_deathsentence(CH *ch, STATUS *status, const short action) {
}
 
void status_dontact(CH *ch, STATUS *status, const short action) {   
}
  
void status_dontmove(CH *ch, STATUS *status, const short action) {
}
  
void status_faith(CH *ch, STATUS *status, const short action) {
}
   
void status_float(CH *ch, STATUS *status, const short action) {
}
 
void status_frog(CH *ch, STATUS *status, const short action) {
}
 
void status_haste(CH *ch, STATUS *status, const short action) {
}
 
void status_innocent(CH *ch, STATUS *status, const short action) {
}
 
void status_invitation(CH *ch, STATUS *status, const short action) {
}

void status_oil(CH *ch, STATUS *status, const short action) {
}
 
void status_petrify(CH *ch, STATUS *status, const short action) {
}
 
void status_poison(CH *ch, STATUS *status, const short action) {
  short dam;
  
  switch(action) {
  case STATUS_UPDATE:
    dam = ch->HP[1] / 8;
    ostrstream ost;
    ost << "{![" << ch->name << "] -" << dam << " Hp{0\n\r" << ends;
    ch->battle->echo(ost.str());
  
    if((ch->HP[0] -= dam) < 0)
      ch->die();
 
    break;
  }
 
  return;
}
 
void status_protect(CH *ch, STATUS *status, const short action) {
}
 
void status_reflect(CH *ch, STATUS *status, const short action) {   
}
  
void status_regen(CH *ch, STATUS *status, const short action) {   
}
  
void status_reraise(CH *ch, STATUS *status, const short action) {
}
   
void status_shell(CH *ch, STATUS *status, const short action) {
}
 
void status_slow(CH *ch, STATUS *status, const short action) {
}
 
void status_sleep(CH *ch, STATUS *status, const short action) {
}
 
void status_stop(CH *ch, STATUS *status, const short action) {
}
 
void status_transparent(CH *ch, STATUS *status, const short action) {
}

void status_undead(CH *ch, STATUS *status, const short action) {
}