#include "clusterworker.h"

clusterworker::clusterworker()
{
}

clusterworker::~clusterworker()
{
}

int clusterworker::init( std::string ip, int port )
{
  cmip = ip;
  cmport = port;
  return 0;
}

int clusterworker::start( unsigned long int ts )
{
  int res = cn.init( cmip, cmport );
  std::cout << "connection initalized "
            << res << "\n";
  ts = 0;
  mainloop();
  cn.closesocket();
  return 0;
}

int clusterworker::mainloop()
{
  int flag;
  flag = 1;
  std::cout << "starting main loop\n";
  int ndone;
  ndone = 0;

  while( flag == 1 )
    {
      //send request work to manager
      //if exit signal end
      //get the data 
      //process data
      //send data
      int smid;
      int ssize;
      char *msg;
      smid = CM_REQUEST_NEWJOB;
      std::cout << "sending ready signal\n";
      cn.write( (char*) (&smid), sizeof(int) );
      std::cout << "waiting for message\n";
      cn.read( (char*) (&smid), sizeof(int) );
      if( smid == CM_END )
        {
          std::cout << "GOT EXIT SIGNAL\n";
          flag = 0;
        }
      else if(smid == CM_DELDATA)
        {
          std::cout << "deleting data\n";
          for( unsigned i = 0; i < sa.size(); i++ )
            delete sa[i];
          sa.clear();
          for( unsigned i = 0; i < sb.size(); i++ )
            delete sb[i];
          sb.clear();
        }
      else if(smid == CM_NEWDATA )
        {
          std::cout << "recieving new data\n";
          int sz;
          cn.read( (char*)(&sz), sizeof(int) );
          int imsize[5];
          cn.read( (char*)imsize, sizeof(int)*5);
          std::cout << "getting: " << imsize[0] 
                    << " " << imsize[1] << " " << imsize[2]
                    << " " << imsize[3] << " " << imsize[4] << "\n";
          for( int i = 0; i < imsize[0]; i++ )
            {
              sa.push_back( new image2d );
              sb.push_back( new image2d );
            }
          std::cout << "getting maps\n";
          mapa.create( imsize[1], imsize[2] );
          mapb.create( imsize[3], imsize[4] );
          cn.read( (char*)(mapa.getimageptr()),
                   sizeof(double)*imsize[1]*imsize[2] );
          std::cout << "got map1\n";
          cn.read( (char*)(mapb.getimageptr()), 
                   sizeof(double)*imsize[3]*imsize[4] );
          std::cout << "got map2\n";
          std::cout << "getting stack 1: ";
          for( int i = 0; i < imsize[0]; i++ )
            {
              sa[i]->create( imsize[1], imsize[2] );
              cn.read( (char*)(sa[i]->getimageptr()), 
                       sizeof(double)*imsize[1]*imsize[2] );
              std::cout << i << " " << std::flush;
            }
          std::cout << "\ngetting stack2: ";
          for( int i = 0; i < imsize[0]; i++ )
            {
              sb[i]->create( imsize[3], imsize[4] );
              cn.read( (char*)(sb[i]->getimageptr()), 
                       sizeof(double)*imsize[3]*imsize[4] );
              std::cout << i << " " << std::flush;
            }
          std::cout << "\n";
        }
      else if(smid == CM_NEWWORK )
        {
          std::cout << "new work\n";
          cn.read( (char*)(&ssize), sizeof(int) );
          msg = new char[ssize];
          cn.read( msg, ssize );
          cwu.unpack( msg, ssize );
          delete [] msg;
          processwork();
          sendresult();
        }
      else if( smid == CM_QUEUE_FINISHED )
        {
          std::cout << "queue finished\n";
        }
      else
        {
          std::cout << "unknown message: " << smid << "\n";
          flag = 0;
        }

      ndone++;
    }
  return 0;
}

int clusterworker::sendresult()
{
  int smid;
  int ssize;
  char *buf;
  smid = CM_JOBRESULT;
  std::cout << "sending results\n";
  cwu.packresult( &buf, ssize );
  cn.write( (char*)(&smid), sizeof(int) );
  cn.write( (char*)(&ssize), sizeof(int) );
  cn.write( buf, ssize );
  delete [] buf;
  return 0;
}

int clusterworker::processwork()
{
  int tx, ty, s, pn;
  cwu.getinput( tx, ty, s, pn );
  std::cout << "processing: " << tx << " " << ty << " " << s << " " << pn << "\n";
  double score;

  score = mi.miscore( *(sa[s]), *(sb[s]), mapa, mapb, tx, ty );
  //  score = random()%50000;
  //  score = score/50000;
  cwu.setresult( score );

  return 0;
}
