/**********************************************************************
This file is part of Crack dot Com's free source code release of Golgotha.
for information about compiling & licensing issues visit this URL
 If that doesn't help, contact Jonathan Clark at 
  golgotha_source@usa.net (Subject should have "GOLG" in it) 
***********************************************************************/

#include "team_api.hh"
#include "memory/array.hh"
#include "math/random.hh"
#include "math/angle.hh"
#include "math/trig.hh"
#include "time/profile.hh"
#include "objs/stank.hh"
#include "objs/goal.hh"

//(OLI) hack for reloading this AI
extern w16 ai_joe_dll_ref;

char *unit_name[] = 
{
  "stank",                      //0
  "peon_tank",                  //1
  "electric_car",               //2
  "rocket_tank",                //3
  "",
  "",
//  "helicopter",                 //4
//  "jet",                        //5
  "engineer",                   //6
  "trike"                       //7
};
const int num_unit_types=sizeof(unit_name)/sizeof(char*);
w16 unit_type[num_unit_types];

char *goodies_name[] = 
{
  "takeover_pad",               //1
  "factory_pad"                 //2
};
const int num_goodies_types=sizeof(goodies_name)/sizeof(char*);
w16 goodies_type[num_goodies_types];

char *formation[] =
//{{{
{
  "      "
  "      "
  "121212"
  "      "
  "1 63 1"
  "  33  ", // stock

  "222222"
  "      "
  "      "
  "      "
  "      "
  "      ", // electric brigade

  "  11  "
  " 1221 "
  "123321"
  "      "
  "      "
  "      ", // hole puncher

  "12221 "
  "23632 "
  "      "
  "      "
  "      "
  "      ", // armored convoy

  "      "
  "      "
  "1 1 1 "
  " 1 1 1"
  "7 7 7 "
  " 7 7 7", // gene's checker

  "  1   "
  " 161  "
  "1   1 "
  "      "
  "      "
  "      ", // peon V

  "  4   "
  " 4 4  "
  "      "
  "      "
  "      "
  "      ", // heli hell

  "111111"
  " 3663 "
  " 3333 "
  "      "
  "      "
  "      ", // rockets R us

  "22    "
  "66    "
  "      "
  "      "
  "      "
  "      ", // small band

  "22    "
  "36    "
  "      "
  "      "
  "      "
  "      ", // yet another small band

  "33    "
  "66    "
  "      "
  "      "
  "      "
  "      ", // yet another small band

  "6     "
  "      "
  "      "
  "      "
  "      "
  "      ", // long shot

  "2222  "
  "3333  "
  "      "
  "      "
  "      "
  "      ", // ouch!
};
//}}}
const int num_formations=sizeof(formation)/sizeof(char*);

enum eDir
{
  N, E, S, W
};

sw16 dirx[] = {0, 1, 0, -1};
sw16 diry[] = {1, 0, -1, 0};


i4_profile_class pf_ai_joe_setup_production("ai_joe_setup_production");
i4_profile_class pf_ai_joe_setup_new_pieces("ai_joe_setup_new_pieces");
i4_profile_class pf_ai_joe_cleanup("ai_joe_cleanup");
i4_profile_class pf_ai_joe_next_spot("ai_joe_next_spot");
i4_profile_class pf_ai_joe_guide_hero("ai_joe_guide_hero");
i4_profile_class pf_ai_joe_think("ai_joe_think");

class ai_joe : public g1_team_api_class
{
public:
  enum eBuildMode 
  { INIT, INITWAIT, IDLE, BUILDWAIT, BUILD, WAITFORPIECE, FORMANDMOVE, RESURRECT };

  i4_float tx,ty;
  sw16 bx,by;
  i4_float prodx,prody;
  eDir dir1, dir2;

  i4_array troop;
  i4_array time;
  i4_array build;
  i4_array goal;
  int form, place, formation_size;
  int build_count;
  int build_wait, retry;
  eBuildMode build_mode;

  w16 goal_type;

  int reload;  // supertank is going to reload ammo

  ai_joe(g1_loader_class *f=0) 
    : troop(100,20), time(50,20), build(18,0), goal(20,10)
  //{{{
  {
    build_mode = INIT;
    form = -1;
    place = 0;
  }
  //}}}

  ~ai_joe()
  //{{{
  {
  }
  //}}}

  void setup_production(i4_float _prodx,i4_float _prody)
  //{{{
  {
    pf_ai_joe_setup_production.start();
    // setup around production site at location

    prodx = _prodx;
    prody = _prody;

    int
      dx = int(prodx - map_width()/2),
      dy = int(prody - map_height()/2);

    int num=0;

    num |= (dx<0)  ?0:8;
    num |= (dy<0)  ?0:4;
    num |= (dx=0; i--)
      if (!troop[i].alive())
        troop.remove(i);
    pf_ai_joe_cleanup.stop();
  }
  //}}}

  int next_spot()
  //{{{ sets next formation spot.. returns false if no more left
  {
    pf_ai_joe_next_spot.start();

    while (place<6*6 && formation[form][place]==' ')
      place++;

    if (place==6*6)
    {
      pf_ai_joe_next_spot.stop();
      return 0;
    }

    int x=(place%6)*2-5, y=5-(place/6)*2;

    bx = (5 + dirx[dir1]*y + dirx[dir2]*x)/2;
    by = (5 + diry[dir1]*y + diry[dir2]*x)/2;

    pf_ai_joe_next_spot.stop();
    return 1;
  }
  //}}}

  void guide_hero()
  //{{{
  {
    pf_ai_joe_guide_hero.start();

    if (health()<=0)
    {
#if 0
      if (build_mode == IDLE)
        build_mode = RESURRECT;
#endif      
      pf_ai_joe_cleanup.stop();
      return;
    }

    if (ammo1()==0 && ammo2()==0 && ammo3()==0 && !reload)
    {
      /*
        jc fixme : send supertank to home base
      tx = map()->player_pad_info[player->get_player_num()].bases[0].x;
      ty = map()->player_pad_info[player->get_player_num()].bases[0].y;

      
      send_convoy(commander()->convoy->global_id, tx, ty);
      reload = 1;
      */
    }
    
    if (reload)
    {
      if (full1() && full2() && full3())
        reload=0;

      pf_ai_joe_cleanup.stop();
      return;
    }

    if (!commander()->attack_target.valid())
    {
      commander()->find_target();
      if (!commander()->attack_target.valid())
      {
        tx = g1_rand(50)%map_width()  + 0.5;
        ty = g1_rand(60)%map_height() + 0.5;

        deploy_unit(commander()->global_id, tx, ty);
      }
    }
    else
    {
      g1_object_class *mp = commander()->attack_target.get();

      if (mp)
      {

        i4_float dx,dy,angle, adiff;
	
        //this will obviously only be true if me->attack_target.ref != NULL    
        dx = (mp->x - (commander()->x+commander()->turet->x));
        dy = (mp->y - (commander()->y+commander()->turet->y));
	
        //aim the turet
	
        angle = i4_atan2(dy,dx);
        i4_normalize_angle(angle);    
        adiff = i4_angle_diff(commander()->base_angle, angle);

        if (adiff<0.04)
          if (mp->id == g1_supertank_type)
            fire2() || fire1() || fire3();
          else
            fire1() || fire3();
        if (angle>commander()->base_angle)
          turn(adiff);
        else
          turn(-adiff);
        strafe(0.4);
      }
    }
    
    pf_ai_joe_guide_hero.stop();
  }
  //}}}

  void guide_units()
  //{{{
  {
    for (int i=0; i0)
        time[i]--;
      else 
      {
        int went=0;

        if (goal.size()>0)
        {
          tx = g1_rand(70)%(map_width()-10) + 5.5;
          ty = g1_rand(80)%(map_height()-10) + 5.5;
          deploy_unit(group[i].id(), tx,ty);
          time[i]=g1_rand(9)%500+500;
        }

        tx = g1_rand(90)%(map_width()-10) + 5.5;
        ty = g1_rand(100)%(map_height()-10) + 5.5;
        deploy_unit(group[i].id(), tx,ty);
        time[i]=g1_rand5()%500+500;
      }
    }
  }
  //}}}

  virtual void object_built(w32 id)
  //{{{
  {
    g1_team_api_class::object_built(id);

    build.add(unit(id));
  }
  //}}}
  
  virtual void object_added(w32 id)
  //{{{
  {
    object_class obj(object(id));
    unit_class u(unit(id));
    int i;

    if (obj.alive())
    {
      if (obj.id()==goodies_type[0])
        goal.add(obj);
      else if (u.alive())
      {
        for (i=0; i ai_joe_def("ai_joe");


// AI joe is now chosen as the default through (g1_set_deault_ai "joe") in scheme/start.scm

//{{{ Emacs Locals
// Local Variables:
// folded-file: t
// End:
//}}}