//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Server.h"
#include "MServerThread.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)

// Use inherited constructor.
_fastcall TMServerThread::TMServerThread(bool CreateSuspended,
    TServerClientWinSocket* ASocket)
     : TServerClientThread( CreateSuspended, ASocket)
     {  }

// Main body of ServerThread
void _fastcall TMServerThread::ClientExecute()
{
  // Set our Thread Priority to whatever we are supposed to be:
  switch(Form1->Priority)
  {
  case 1:  Priority = tpIdle; break;
  case 2:  Priority = tpLowest; break;
  case 3:  Priority = tpLower; break;
  case 4:  Priority = tpNormal; break;
  case 5:  Priority = tpHigher; break;
  case 6:  Priority = tpHighest; break;
  case 7:  Priority = tpTimeCritical; break;
  }

 //See if we can get a stream.
 try {
 TWinSocketStream *pStream = new TWinSocketStream(
                        ClientSocket, 60000);
  try
  {
   // We got a stream, so start listening on it.
   while(!Terminated && ClientSocket->Connected)
   {
    if (pStream->WaitForData(60000));
    {
      if (pStream->Read(&ReceiveBuf,sizeof(ReceiveBuf)) == sizeof(ReceiveBuf) )
      {
        // Generate the Mandelbrot Pixels.
        Mandelbrot(ReceiveBuf.sx,ReceiveBuf.sy,
                   ReceiveBuf.ex,ReceiveBuf.ey,
                   ReceiveBuf.maxIter, ReceiveBuf.rMin,
                   ReceiveBuf.rInc,ReceiveBuf.iMin,
                   ReceiveBuf.iInc,pStream);
      }  // got the data.
      else
        ClientSocket->Close(); // didn't get data.
    } // end wait for data.


   } // End while not terminated & still connected.
  } // end try
  // Next line NOT ANSI
  __finally { delete pStream;}

 } catch (...) { HandleException(); }



} // end TMServerThread::ClientExecute.

unsigned char TMServerThread::iterate(Complex zInit, int maxIter)
{


  Complex z = zInit;
  int cnt = 0;

   while( ( z.x * z.x + z.y * z.y <= 4.0 ) && (cnt < maxIter) )
   {
     z = complexSquare(z);
     z.x += zInit.x;
     z.y += zInit.y;
     cnt++;
   }
   return((unsigned char) (cnt % 255) );

} // end TMServerThread::iterate

void TMServerThread::Mandelbrot(int sx, int sy,int ex, int ey,
                    int maxIter, double long realMin,
                    double long realInc, double long imagMin,
                    double long imagInc,TWinSocketStream *pStream)
{
 Complex z;
 int x,y;
 unsigned char cnt;



 // Set our timeout to 50 seconds.
 pStream->TimeOut = 50000;

 // Allicate an array to hold one row.
 //unsigned char* Array = new unsigned char[ex-sx+1];
 unsigned char Array[10000];
 int index = 0;



 z.y = imagMin + ((double long)sy * imagInc);
 for(y = sy; y <= ey; y++, z.y += imagInc)
 {

    // Set the WorkDone variable each time through.
    if ( (ey - sy) > 0)
    {
      WorkDone = (int) (((float)y / (float)(ey-sy)) * 100.0);
    }

    z.x = realMin + ((double long)sx * realInc);
    for(x = sx; x <= ex; x++,z.x += realInc)
    {
      cnt = iterate(z,maxIter);

      if ( cnt == maxIter)
         Array[index++] = 0;
      else
        Array[index++] = cnt;

       // If the array gets full, write it out.
       if (index == 10000)
       {
         while (index != 0)
         {
          int count = pStream->Write(&Array,index);
          index = index - count;
          }
       }

    } // end X loop
    // Now that we are done with a row, send it.
   /*
    for(int i = 0; i < 300; i++)
      pStream->Write(&Array[i],1);

    if ( pStream->Write( &Array,sizeof(Array)) == sizeof(Array))
    {
     // good stuff.
     Array[0] = 1;
    }
          */
 } // end for Y.

 // Done, but some left in array to send.
 while (index != 0)
 {
   int count = pStream->Write(&Array,index);
   index = index - count;
 }

 // Clean up after ourselves.
 //delete Array;

} // end TMServerThread::Mandelbrot.
