//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include<exception>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "MyImage2"
#pragma resource "*.dfm"

TForm1 *Form1;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}

int TForm1::findImage(AnsiString fileName){

IMAGEHANDLER imgHandler;
for(unsigned int i = 0; i < clientList.size(); i++){

        imgHandler = clientList.at(i);
        
        if(imgHandler.fileName == fileName)
                return i;
}

return -1;

}

//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
        ServerSocket1->Port = 1053;
        ServerSocket1->Active = True;

        lastImg.xPos = 0;
        lastImg.yPos = 0;
        lastImg.width = 0;
        lastImg.height = 5;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
        ServerSocket1->Active = False;
}



TPoint TForm1::getposition(int maxWindowWidth, int topSpace, int leftSpace,
int lastWidth, int lastHeight, TPoint lastPos, int currWidth, int currHeight){

  TPoint coord;

  if(maxWindowWidth <= lastPos.x + lastWidth + leftSpace + currWidth){
        coord = Point(leftSpace, lastPos.y + lastHeight + topSpace);
  } else {
        coord = Point(lastPos.x + lastWidth + leftSpace, lastPos.y);
  }

  return coord;
}

TPoint getpositionafterdelete(TPoint lastPos, int width, int height, int leftSPace){

        TPoint coord;
        coord = Point(lastPos.x - leftSPace - width, lastPos.y);

        return coord;
}

TRect resize(Graphics::TBitmap *bitmap, int desiredWidth){

        int width = bitmap->Width;
        int height = bitmap->Height;

        double wsp = width / (double)desiredWidth;

        TRect tRect = Rect(Point(0,0), Point(desiredWidth, (int)(height / wsp)));
        return tRect;
}

void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender,
      TCustomWinSocket *Socket)
{
        int index;
        int messageSize = Socket->ReceiveLength();

        MyImage2 *myImage;
        char *buffer;

        //klient jest
        if( (index = findImage(Socket->RemoteAddress)) != -1 ){

                myImage = clientList[index].image;

                if(messageSize == sizeof(char)){

                        AnsiString messageText = Socket->ReceiveText();

                          if(messageText == "s"){
                                TFileStream *fStream;
                                fStream = new TFileStream(Socket->RemoteAddress + ".bmp", fmCreate | fmShareDenyNone);
                                clientList[index].fStream = fStream;
                                Socket->SendText('g');
                          }
                          else if (messageText == "f"){

                                clientList[index].fStream->Free();
                                Graphics::TBitmap *bitmap = new Graphics::TBitmap();

                                try{
                                        bitmap->LoadFromFile(Socket->RemoteAddress + ".bmp");
                                        myImage->Canvas->StretchDraw(resize(bitmap, 220), bitmap);

                                } __finally{

                                        delete bitmap;
                                }

                          } else {

                                if( clientList[index].size - messageSize > 0 ){

                                        try{
                                                buffer = new char[messageSize];
                                                Socket->ReceiveBuf(buffer, messageSize);
                                                clientList[index].fStream->WriteBuffer(buffer, messageSize);

                                        } __finally{

                                                delete [] buffer;
                                        }

                                        clientList[index].size -= messageSize;
                                } else {

                                                                try{
                                        buffer = new char[messageSize];
                                        Socket->ReceiveBuf(buffer, messageSize);
                                        clientList[index].fStream->WriteBuffer(buffer, messageSize);

                                } __finally{

                                        delete [] buffer;

                                }

                             clientList[index].size -= messageSize;

                                     Socket->SendText("k");

                                }
                          }

                } else {

                        
                        if(messageSize < 10){

                                try{

                                     clientList[index].size = Socket->ReceiveText().ToInt();
                                     Socket->SendText("r");

                                } catch (...){


                                       if( clientList[index].size - messageSize > 0 ){

                                        try{
                                                buffer = new char[messageSize];
                                                Socket->ReceiveBuf(buffer, messageSize);
                                                clientList[index].fStream->WriteBuffer(buffer, messageSize);

                                        } __finally{

                                                delete [] buffer;

                                        }

                                        clientList[index].size -= messageSize;


                                       } else {

                                                                       try{
                                        buffer = new char[messageSize];
                                        Socket->ReceiveBuf(buffer, messageSize);
                                        clientList[index].fStream->WriteBuffer(buffer, messageSize);

                                } __finally{

                                        delete [] buffer;

                                }

                             clientList[index].size -= messageSize;

                                                Socket->SendText("k");

                                       }

                                }

                        } else {


                        if( clientList[index].size - messageSize > 0 ){

                                try{
                                        buffer = new char[messageSize];
                                        Socket->ReceiveBuf(buffer, messageSize);
                                        clientList[index].fStream->WriteBuffer(buffer, messageSize);

                                } __finally{

                                        delete [] buffer;

                                }

                             clientList[index].size -= messageSize;

                        } else {

                                                        try{
                                        buffer = new char[messageSize];
                                        Socket->ReceiveBuf(buffer, messageSize);
                                        clientList[index].fStream->WriteBuffer(buffer, messageSize);

                                } __finally{

                                        delete [] buffer;

                                }

                             clientList[index].size -= messageSize;

                                Socket->SendText("k");
                        }

                        }

                }

        } else {

                if(messageSize == sizeof(char)){

                        AnsiString messageText = Socket->ReceiveText();
                        IMAGEHANDLER iHand;

                        if(messageText == "s"){

                                TFileStream *tStream = new TFileStream(Socket->RemoteAddress + ".bmp", fmCreate | fmShareDenyNone);

                                iHand.fStream = tStream;

                                TPoint pos = getposition(1200, 5, 5, lastImg.width, lastImg.height,
                                Point(lastImg.xPos, lastImg.yPos), 220, 165);

                                myImage = new MyImage2(this);
                                myImage->path = Socket->RemoteAddress + ".bmp";
                                myImage->SetBounds(pos.x, pos.y, 220, 165);
                                myImage->Visible = true;
                                myImage->Transparent = false;
                                myImage->OnClick = MyImageClick;
                                myImage->Parent = this;

                                TLabel *computerName = new TLabel(this);
                                computerName->Caption = Socket->RemoteAddress;
                                computerName->Left = pos.x;
                                computerName->Top = pos.y;
                                computerName->Font->Color = clBlack;
                                computerName->Font->Size = 18;
                                computerName->Visible = true;
                                computerName->Parent = this;
                                computerName->Transparent = true;

                                lastImg.xPos = pos.x;
                                lastImg.yPos = pos.y;
                                lastImg.width = 220;
                                lastImg.height = 165;

                                iHand.fileName = Socket->RemoteAddress;
                                iHand.image = myImage;
                                iHand.label = computerName;

                                clientList.push_back(iHand);


                                Socket->SendText('g');

                        }
                }
        }

}
//---------------------------------------------------------------------------

void __fastcall TForm1::func(TObject *Sender, TCloseAction &Action){

delete bigImage;

}


void __fastcall TForm1::MyImageClick(TObject *Sender)
{

try{
        MyImage2 *myImage = (MyImage2 *) Sender;

        TForm *newForm = new TForm(this);
        bigImage = new MyImage2(newForm);

        bigImage->Left = 0;
        bigImage->Top = 0;

        bigImage->Visible = true;
        bigImage->Parent = newForm;
        bigImage->Picture->Bitmap->LoadFromFile(myImage->path);
        bigImage->Width = bigImage->Picture->Bitmap->Width;
        bigImage->Height = bigImage->Picture->Bitmap->Height;

        newForm->Width = bigImage->Width;
        newForm->Height = bigImage->Height;
        newForm->Show();

        newForm->OnClose = func;


} catch (...){

        ShowMessage("Trwa zapis do pliku! Nie jest możliwy podgląd.");
}

}
//---------------------------------------------------------------------------

void __fastcall TForm1::ServerSocket1ClientDisconnect(TObject *Sender,
      TCustomWinSocket *Socket)
{
        int index;
        if( (index = findImage(Socket->RemoteAddress)) != -1 ){

                IMAGEHANDLER imgHand = clientList[index];
                imgHand.label->Free();
                imgHand.image->Free();

                clientList.erase(clientList.begin() + index);

                TPoint pt = getpositionafterdelete(Point(lastImg.xPos, lastImg.yPos),
                                                lastImg.width,lastImg.height, 5);

                lastImg.xPos = pt.x;
                lastImg.yPos = pt.y;
        }


        ShowMessage("Klient " + Socket->RemoteAddress + " rozłączył się!");
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

void __fastcall TForm1::ServerSocket1ClientConnect(TObject *Sender,
      TCustomWinSocket *Socket)
{
        ShowMessage("Zalogował się klient: " + Socket->RemoteAddress);
}
//---------------------------------------------------------------------------


void __fastcall TForm1::ServerSocket1ClientError(TObject *Sender,
      TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
        ShowMessage("Nastąpił błąd klienta " + Socket->RemoteAddress + " !");

        ServerSocket1ClientDisconnect(Sender, Socket);
}
//---------------------------------------------------------------------------

