#include "Traj.h"
#include "Globals.h"
#include "Stations.h"
#include "stdlib.h"


// 1) find traj
// 2) calculate time of this traj
// 3) <> with prev traj time
// 4) if this time < DataTime then EXIT


static CMatrix sm, m;
static int size_m = 0, data_time = 0, trajlen = 0;

static int start_p, end_p;


//------------ Init Traj --------------
void InitTraj(struct Traj *t){
 t -> c = 0;
 t -> time = 0;
}

//------------ Destroy Traj --------------
void DestTraj(struct Traj *t){
 t -> c = 0;
 t -> time = 0;
 free(t -> point);
}

//------------ Add Point to Traj --------------
void AddPointTraj(struct Traj *t, int p){
 t -> c++;
 if (t -> point == NULL)
   t -> point = (int*) malloc(sizeof(int)*(t->c) );
    else
      t -> point = (int*) realloc(t -> point,  sizeof(int)*(t->c));
 t -> point[t->c-1] = p;
}

//------------ Find Traj Time --------------
int FindTrajTime(struct Traj *t, CMatrix m1){
 int i, j, res=0, h;
  for (i = 1; i<t->c; i++)
  {
   res += m1[ t->point[i] ][ t->point[i-1] ];
    for (j=0;  j<i; j++)
     if (t->point[i] == t->point[j]) {h=0; break;} else h=5;
   res += 5;  
  } 

  t->time = res;
 return res;
}



//------------ PRINT Traj --------------
void PrintTraj(struct Traj *t, struct Stations *stat){
int i = 0;

if (t->c <= 0) { printw("\n   Cannot find :( "); return;}
  printw("\n   %s", stat->items[  t->point[t->c-1] ]);
   for (i = 1; i < t->c; i++) {
    printw(" -> %s", stat->items[  t->point[t->c-1 - i] ]);
   }

  printw("\n   Total time: %d", t->time);
}



//------------ FIND TRAJECOTRY -------------
// 3 - now forming trajectory
// -1 - go back
//

#define FORMING_TRAJ 3
#define POOR_VARIANT -1
#define BAD_PASS -2

char FindTraj(int p, int i, struct Stations *stat){
// int i = p;
 int res = BAD_PASS;
 int dead = 0;

 WasStation(stat, p);
// PrintWasEscStations(stat);


//---------------- Forming of trajectory ------------------
 if (end_p == p) {
 if (TestStations(stat))

    {
       printw("\n Good theme! ");
      DestTraj(&cur_traj);
      InitTraj(&cur_traj);
     return FORMING_TRAJ;
    }
  else return POOR_VARIANT; }


//-------------------- Make a pass ------------------------
     for (i=0; i<size_m; i++)
      if (sm[i][p] > 0)
      {
        dead = 1;

        sm[i][p] = 0;

 //      printw("    Go1 - %s -> %s    ", stat->items[p], stat->items[i]);
         res = FindTraj(i,p, stat);
   //    printw("    Es1 - %s -> %s    ", stat->items[p], stat->items[i]);
        sm[i][p] = 1;

         switch (res) {
            case FORMING_TRAJ : AddPointTraj(&cur_traj, i);  return FORMING_TRAJ;  break;
          }
      }

//---------------- Deadlock? Make a pass  -----------------
   if (dead)
    for (i=0; i<size_m; i++)
      if (sm[p][i] > 0)
      {
        sm[p][i] = 0;
  //      printw("    Go2 - %s -> %s    ", stat->items[p], stat->items[i]);
         res = FindTraj(i,p, stat);
        sm[p][i] = 1;
    //     printw("    Es2 - %s -> %s    ", stat->items[p], stat->items[i]);

         switch (res) {
            case FORMING_TRAJ : AddPointTraj(&cur_traj, i);  return FORMING_TRAJ;  break;
          }
      }
     EscStation(stat, p);

//-------------------------- Poor -------------------------
 return 0;
}




//----------- Base function ---------------
struct Traj BaseFunc(struct Stations *stat, int sel, int t, CMatrix m1, CMatrix sm1){

  int trajlen;


  end_p = GetStationID(EndStat, stat);
  start_p = sel;
  data_time = t;

  trajlen = stat->c-1;

  m = m1;
  sm = sm1;
  size_m = stat -> c;

  InitTraj(&cur_traj);
  ClearWasEscStations(stat);
  WasStation(stat, start_p);

  if (FindTraj(start_p,start_p, stat) == 3)
    AddPointTraj(&cur_traj, start_p);

  
 return cur_traj;
}
