//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include <stdio.h>
#include <shellapi.h>

#include "AllBox.h"
#include "MiniChat_userlist.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "actimg"
#pragma link "CoolForm"
#pragma link "DialUp"
#pragma resource "*.dfm"


/*
  Status
      0  escucha
      1  new-msg
      2  enviando-msg
*/

TBoxes *Boxes;
//---------------------------------------------------------------------------
__fastcall TBoxes::TBoxes(TComponent* Owner)
    : TForm(Owner)
{
    InMessage = new TStringList;

    BoxActive = 0;
    Status = 0;
  	TrayMessage(NIM_ADD);
    TrayMessage(NIM_MODIFY);

    // Cargamos la lista de usuarios...
    LoadUserList();
    MiniChatList->UserList->Items = para->Items;
    for ( int i=0; i<20; i++ )
      OutChats[i] = new  TNMMsg(this);
}
//---------------------------------------------------------------------------
void __fastcall TBoxes::LoadUserList( void )
{
 FILE *users;
 char buffer[200];
 AnsiString Name;
 NumUsers = 0;

 if ( (users = fopen( "users.cfg", "r" ) ) != NULL )
 {
   while ( !feof( users ) && NumUsers < 45 )
   {
     fgets( buffer, 200, users );
     if ( StrLen( buffer ) >= 10 && buffer[0]!='#' )
     {
         Name = AnsiString( scanUntil( buffer, 32 ) + 1 );
         TranslateIP[NumUsers] = AnsiString( buffer );
         Name = Name.SetLength(Name.Length()-1);
         para -> Items -> Add( Name );
         NumUsers ++;
     }
   }

   fclose( users );
 }

}
//---------------------------------------------------------------------------
char * __fastcall TBoxes::scanUntil( char *text, char Terminador )
{
 char *buff;

 buff = text;

 while ( *buff != '\0' && *buff != Terminador )
  buff++;

 *buff = '\0';

 return buff;
}
//---------------------------------------------------------------------------
void __fastcall TBoxes::DrawItem(TMessage& Msg)
{
     IconDrawItem((LPDRAWITEMSTRUCT)Msg.LParam);
     TForm::Dispatch(&Msg);
}
//---------------------------------------------------------------------------
void __fastcall TBoxes::MyNotify(TMessage& Msg)
{
    POINT MousePos;

    switch(Msg.LParam)
    {
        case WM_RBUTTONUP:
            if ( GetCursorPos(&MousePos) )
            {
                PopupMenu1->PopupComponent = Boxes;
                SetForegroundWindow(Handle);
                PopupMenu1->Popup(MousePos.x, MousePos.y);
                PopupMenu1->PopupComponent = 0;
            }
            else
                Show();
            break;
        case WM_LBUTTONDBLCLK:
              Properties1Click(0);
            break;
/*
        case WM_LBUTTONUP:
              Properties1Click(0);
            break;
*/            
        default:
            break;
    }
    TForm::Dispatch(&Msg);
}
//---------------------------------------------------------------------------
void __fastcall TBoxes::ActiveImage4Click(TObject *Sender)
{
 Visible = false;

 if ( MiniChatList -> Visible )
    MiniChatList -> Visible = false;

}
//---------------------------------------------------------------------------
void __fastcall TBoxes::FormDestroy(TObject *Sender)
{
  for ( int i=0; i<20; i++ )
   delete OutChats[i];

    delete InMessage;
	TrayMessage(NIM_DELETE);
}
//---------------------------------------------------------------------------
bool __fastcall TBoxes::TrayMessage(DWORD dwMessage)
{
   NOTIFYICONDATA tnd;
   PSTR pszTip;

   pszTip = TipText();

   tnd.cbSize          = sizeof(NOTIFYICONDATA);
   tnd.hWnd            = Handle;
   tnd.uID             = IDC_MYICON;
   tnd.uFlags          = NIF_MESSAGE | NIF_ICON | NIF_TIP;
   tnd.uCallbackMessage	= MYWM_NOTIFY;

   if (dwMessage == NIM_MODIFY)
    {
        tnd.hIcon		= IconHandle();
        if (pszTip)
           lstrcpyn(tnd.szTip, pszTip, sizeof(tnd.szTip));
	    else
        tnd.szTip[0] = '\0';
    }
   else
    {
        tnd.hIcon = NULL;
        tnd.szTip[0] = '\0';
    }

   return (Shell_NotifyIcon(dwMessage, &tnd));
}
//---------------------------------------------------------------------------
HANDLE __fastcall TBoxes::IconHandle(void)
{
    switch ( Status )
    {
     case 1:
        return imagenOFF -> Picture->Icon->Handle;
    }
 return imagenOn -> Picture->Icon->Handle;
}
//---------------------------------------------------------------------------
PSTR __fastcall TBoxes::TipText(void)
{
  switch( Status )
  {
   case 0:
          return ("Escuchando nuevos mensajes");
   case 1:
          return ("Tiene mensajes nuevos");
   case 2:
          return ("Enviando Mensaje");
  }
  return ("Código de STATUS DESCONOCIDO");
}

//---------------------------------------------------------------------------
LRESULT IconDrawItem(LPDRAWITEMSTRUCT lpdi)
{
	HICON hIcon;

	hIcon = (HICON)LoadImage(g_hinst, MAKEINTRESOURCE(lpdi->CtlID), IMAGE_ICON,
		16, 16, 0);
	if (!hIcon)
		return(FALSE);

	DrawIconEx(lpdi->hDC, lpdi->rcItem.left, lpdi->rcItem.top, hIcon,
		16, 16, 0, NULL, DI_NORMAL);

	return(TRUE);
}
//---------------------------------------------------------------------------
void __fastcall TBoxes::Properties1Click(TObject *Sender)
{
 Visible = true;
}
//---------------------------------------------------------------------------
void __fastcall TBoxes::Acercade1Click(TObject *Sender)
{
 ShowMessage( "JD soft.\nBipBip es un programa desarrollado por:\nJosé David Guillén\ny distribuido por Informática D.J.  [ www.infdj.com ]");
}
//---------------------------------------------------------------------------
void __fastcall TBoxes::Shutdown1Click(TObject *Sender)
{
  Close();
}
//---------------------------------------------------------------------------
void __fastcall TBoxes::FormCloseQuery(TObject *Sender, bool &CanClose)
{
/*
  if ( MessageDlg( "Si sale ahora del programa, no podrá recibir los mensajes en tiempo real.\n¿Salir de todas formas?", mtWarning, TMsgDlgButtons() << mbNo << mbYes, 0 ) == mrNo )
    CanClose = false;
  else
*/
    MiniChatList->Close();
}
//---------------------------------------------------------------------------

////     TrayMessage(NIM_MODIFY);





void __fastcall TBoxes::ActiveImage2Click(TObject *Sender)
{
  // Vemos que mensajes tenemos en nuestra IN-BOX
  LeeMensajes( "inbox\\" );

  BoxActive = 1;

  // Listado de Mensajes
  AllBox -> Visible = true;

  // Descripción del mensaje
  Label1 -> Caption = "Para:";      para->Visible = false;
  Label2 -> Caption = "Asunto:";    asunto->Visible = false;
  Enviar->Caption = "&Enviar";      Enviar->Visible = false;
  Mensaje->ReadOnly = false;        Mensaje->Lines->Clear();
  Mensaje->Visible = false;

  // MiniChat
  LineChat->Visible = false;
  MiniChat->Visible = false;
}
//---------------------------------------------------------------------------
void __fastcall TBoxes::LeeMensajes(char *carpeta)
{
  // Lee, examina y añade al ALLbox,,,
  TSearchRec sr;
  int iAttributes = 0;
  AllBox->RowCount = 1;
  iAttributes |= faReadOnly | faHidden | faSysFile | faArchive | faAnyFile;
  iAttributes = 0xFF;

  AllBox->Cells[0][AllBox->RowCount-1] = "";    AllBox->Cells[1][AllBox->RowCount-1] = "";  AllBox->Cells[2][AllBox->RowCount-1] = "";  AllBox->Cells[3][AllBox->RowCount-1] = "";
  if (FindFirst( AnsiString( AnsiString(carpeta)+"*.txt" ).c_str(), iAttributes, sr) == 0)
  {
     AllBox->Enabled = true;
//    if (sr.Attr == iAttributes)
    {
      AllBox->Cells[3][AllBox->RowCount-1] = sr.Name;
      ExtractInfo( (sr.Name).c_str(), carpeta );
    }
    while (FindNext(sr) == 0)
    {
//      if (sr.Attr == iAttributes)
      {
        AllBox->RowCount += 1;
        AllBox->Cells[3][AllBox->RowCount-1] = sr.Name;
        ExtractInfo( (sr.Name).c_str(), carpeta );
      }
    }
  } else {
   AllBox->Enabled = false;
  }
  FindClose(sr);
}
//---------------------------------------------------------------------------
void __fastcall TBoxes::ExtractInfo(char *filename, AnsiString Box)
{
 FILE *msg;
 char buffer[200];
 AnsiString buf;

 AnsiString filenameBOX = Box + AnsiString(filename);

 AllBox->Cells[0][AllBox->RowCount-1] = AnsiString( filename ).SubString( 14, 5 );

 if ( ( msg = fopen( filenameBOX.c_str(), "r" ) ) != NULL )
 {
  fgets( buffer, 199, msg );
  buf = buffer;

  AllBox->Cells[1][AllBox->RowCount-1] = TranslateName( buf.SetLength( buf.Length() -1 ) );

  fgets( buffer, 199, msg );
  buf = buffer;
  AllBox->Cells[2][AllBox->RowCount-1] = buf.SetLength( buf.Length() - 1 );
  fclose( msg );
 }

}
//---------------------------------------------------------------------------
AnsiString __fastcall TBoxes::TranslateName( AnsiString name )
{
 for ( int I=0; I < NumUsers; I++ )
 {
   if ( TranslateIP[ I ] == name )
     return para->Items->Strings[I];
 }
 return name;
}
//---------------------------------------------------------------------------
void __fastcall TBoxes::ActiveImage1Click(TObject *Sender)
{
  // Listado de Mensajes
  AllBox -> Visible = false;

  // Descripción del mensaje
  Label1 -> Caption = "Para:";      para->Visible = true;
  Label2 -> Caption = "Asunto:";    asunto->Visible = true;
  Enviar -> Caption = "&Enviar";    Enviar->Visible = true;
  Mensaje->ReadOnly = false;        Mensaje->Lines->Clear();
  Mensaje->Visible = true;
  FechaMsg->Visible = false;

  // MiniChat
  LineChat->Visible = false;
  MiniChat->Visible = false;
}
//---------------------------------------------------------------------------

void __fastcall TBoxes::EnviarClick(TObject *Sender)
{
  if ( Enviar->Caption == "&Borrar!!" )
  {
   DeleteFile( (BoxActive == 1 ? "inbox\\" : "outbox\\" ) + AllBox->Rows[AllBox->Row]->Strings[3] );
   if ( BoxActive == 1 )
    ActiveImage2Click(0);
   else
    ActiveImage3Click(0);
   return;
  }

  char FileMessage[80];

  if ( para->ItemIndex != -1 )
  {
   unsigned short year, month, day;
   unsigned short h, m, s, ss;
   TDateTime::CurrentDate().DecodeDate( &year, &month, &day );
   TDateTime::CurrentTime().DecodeTime( &h, &m, &s, &ss );

//   FileMessage = Format( "outbox\\%02d%02d%02d-%02d%02d%02d.txt", OPENARRAY(TVarRec, (year, month, day, h, m, ss)) );
   sprintf( FileMessage, "outbox\\%02d-%02d-%02d @ %02d.%02d'%02d.txt", year, month, day, h, m, ss );

   Mensaje -> Lines -> Insert( 0, asunto->Text );
   Mensaje -> Lines -> Insert( 0, TranslateIP[para->ItemIndex] );
   Mensaje -> Lines -> SaveToFile( FileMessage );
   Mensaje -> Lines -> Clear();
   asunto->Text = "";
   para->Text = "";

  EnviaMensaje( AnsiString(FileMessage) );
  if ( asunto->Text.Pos( "$-" ) == 1 )
          DeleteFile( AnsiString(FileMessage) );
  } else {
   ShowMessage( "Debe indicar el destinatario..." );
  }
}
//---------------------------------------------------------------------------

void __fastcall TBoxes::ActiveImage3Click(TObject *Sender)
{
  LeeMensajes( "outbox\\" );

  BoxActive = 2;

  // Listado de Mensajes
  AllBox -> Visible = true;

  // Descripción del mensaje
  Label1 -> Caption = "Para:";      para->Visible = false;
  Label2 -> Caption = "Asunto:";    asunto->Visible = false;
  Enviar->Caption = "&Enviar";      Enviar->Visible = false;
  Mensaje->ReadOnly = false;        Mensaje->Lines->Clear();
  Mensaje->Visible = false;

  // MiniChat
  LineChat->Visible = false;
  MiniChat->Visible = false;
}
//---------------------------------------------------------------------------
void __fastcall TBoxes::SendNowTimer(TObject *Sender)
{
  int OldStatus = Status;
  // Damos salida a todos los mensajes pendientes...
  TSearchRec sr;
  int iAttributes = 0xFF;

  if (FindFirst( AnsiString( "outbox\\*.txt" ).c_str(), iAttributes, sr) == 0)
  {
    EnviaMensaje( "outbox\\"+sr.Name );
    while (FindNext(sr) == 0)
     EnviaMensaje( "outbox\\"+sr.Name );
  }
  FindClose(sr);
  ///
  Status = OldStatus;     TrayMessage(NIM_MODIFY);
}
//---------------------------------------------------------------------------

void __fastcall TBoxes::AllBoxDblClick(TObject *Sender)
{
  // Mostramos el mensaje seleccionado...
  Status = 0; TrayMessage(NIM_MODIFY);

  // Listado de Mensajes
  AllBox -> Visible = false;

  // Descripción del mensaje
      para->Visible = false;
      asunto->Visible = false;
  Enviar->Caption = "&Borrar!!";      Enviar->Visible = true;
  Mensaje->ReadOnly = true;
  Mensaje->Visible = true;
  FechaMsg->Visible = true;
  FechaMsg->Caption = AllBox->Rows[AllBox->Row]->Strings[3];

  // MiniChat
  LineChat->Visible = false;
  MiniChat->Visible = false;


  Mensaje->Lines->LoadFromFile( (BoxActive == 1 ? "inbox\\" : "outbox\\" ) + AllBox->Rows[AllBox->Row]->Strings[3] );
  Mensaje->Lines->Delete( 0 );
  Mensaje->Lines->Delete( 0 );
  Label1 -> Caption = "De:\t" + AllBox->Rows[AllBox->Row]->Strings[1];
  Label2 -> Caption = "Asunto:  " + AllBox->Rows[AllBox->Row]->Strings[2];
}
//---------------------------------------------------------------------------

void __fastcall TBoxes::ActiveImage5Click(TObject *Sender)
{
 // Linea Anterior
 if ( BoxActive )
 {
   if ( AllBox->Row > 0 )
   {
    AllBox->Row--;
    if ( AllBox->Visible == false )
                    AllBoxDblClick( 0 );
   }
 }
}
//---------------------------------------------------------------------------

void __fastcall TBoxes::ActiveImage6Click(TObject *Sender)
{
 // Linea Siguiente
 if ( BoxActive )
 {
   if ( AllBox->Row < (AllBox->RowCount-1) )
   {
    AllBox->Row++;
    if ( AllBox->Visible == false )
                    AllBoxDblClick( 0 );
   }
 }
}
//---------------------------------------------------------------------------
void __fastcall TBoxes::EnviaMensaje( AnsiString FileName )
{
 Status = 2;     TrayMessage(NIM_MODIFY);


    OutBox->TimeOut = 20000;
    OutBox->ReportLevel = Status_Basic;
    OutBox->FromName = OutBox->LocalIP;
    OutBox->Port = 6711;

    TStringList *OutMessage;

    try {
        OutMessage = new TStringList;
        OutMessage->LoadFromFile( FileName );
        OutBox->Host = OutMessage->Strings[0];

        // Archivo
//        OutBox->PostIt( FileName.SubString( 8, FileName.Length() - 7 ) );
        OutBox->FromName = "BeginMessage";
        OutBox->PostIt( OutBox->LocalIP );
        OutBox->FromName = OutBox->LocalIP;


        for ( int I=1; I < OutMessage->Count; I++ )
          OutBox->PostIt( OutMessage->Strings[I] );

        OutBox->FromName = "EndMessage";
        if (  OutBox->PostIt( FileName.SubString( 8, FileName.Length() - 7 ) ) .AnsiPos( "OK" ) != 0 )
        {
            sndPlaySound("outbox\\msgout.wav", SND_ASYNC | SND_FILENAME);
            DeleteFile( FileName );
        }
        else
            sndPlaySound("outbox\\msgfail.wav", SND_ASYNC | SND_FILENAME);
        delete OutMessage;
    }catch(...){
      // nothing
      sndPlaySound("outbox\\msgfail.wav", SND_ASYNC | SND_FILENAME);
//        ShowMessage( "El mensaje NO pudo ser ENVIADO.\nPuede ser que el equipo no exista.\n(cada 5 minutos, se reintentará su envio)" );
    }
 Status = 0;     TrayMessage(NIM_MODIFY);
}
//---------------------------------------------------------------------------
void __fastcall TBoxes::InBoxMSG(TComponent *Sender,
      const AnsiString sFrom, const AnsiString sMsg)
{
       if ( sFrom == "BeginMessage" && InMessage->Count > 0 )
       {
         InMessage->Insert( 0, sMsg );
         InMessage->Add("-------------------------------\nColision en la red detectada ]cabecera desordenada o mezclada[\n-------------------------------");
       }

       if ( sFrom == "EndMessage" )
       {
        if ( InMessage->Strings[1].Pos( "$-" ) == 1 )
        {
          // Esto es un comando de control, asi que lo procesamos de forma especial

          // Apagar el equipo
          if ( InMessage->Strings[1].UpperCase() == "$-APAGAR" )
               ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE | EWX_POWEROFF, 0);
          // Cortar la conexion a internet
          if ( InMessage->Strings[1].UpperCase() == "$-MODEM" )
                 DialUp1 -> GetConnections();
          InMessage->Clear();
        } else {
          InMessage->SaveToFile( "inbox\\"+sMsg );
          InMessage->Clear();
          Status = 1; TrayMessage(NIM_MODIFY);
          sndPlaySound("inbox\\newmsg.wav", SND_ASYNC | SND_FILENAME);
          if ( Visible == false )
          {
              NewMessage->Enabled = true;
          //            Visible = true;
          }
        }
       } else
         InMessage->Add(sMsg);
}
//---------------------------------------------------------------------------


void __fastcall TBoxes::ActiveImage7Click(TObject *Sender)
{
  LineChat->Visible = true;

      // MiniChat
      // Mostramos tb. la lista de usuarios a los que mandamos nuestras notas...
      LineChat->Visible = true;
      MiniChat->Visible = true;

  if ( MiniChat -> Visible )
  {
      MiniChatList -> Visible = !MiniChatList->Visible;
  }
      // Listado de Mensajes
      AllBox -> Visible = false;

      // Descripción del mensaje
            para->Visible = false;
          asunto->Visible = false;
          Enviar->Visible = false;
         Mensaje->Visible = false;

      MiniChatList->Left = Left + Width;
      MiniChatList->Top  = Top+50;
}
//---------------------------------------------------------------------------

void __fastcall TBoxes::LineChatKeyPress(TObject *Sender, char &Key)
{
  if ( Key == VK_RETURN && !LineChat->Text.IsEmpty() )
  {
    // ...lo subimos pa'rriba
    MiniChat->Lines->Add( LineChat->Text );
    // Enviamos el mensaje, a todos los usuarios marcados en el UserList
    for ( msgI=0; msgI < MiniChatList->UserList->Items->Count; msgI++ )
    {
        if ( MiniChatList->UserList->Checked[msgI])
        {
            try{
                int LineOut = msgI < 20 ? msgI : 0;
                OutChats[LineOut]->ReportLevel = Status_None;
                OutChats[LineOut]->Host = TranslateIP[ msgI ];
                OutChats[LineOut]->FromName = OutBox->LocalIP;
                OutChats[LineOut]->Port = 6712;
                OutChats[LineOut]->TimeOut = 250;
                OutChats[LineOut]->PostIt( LineChat->Text );
/*
                OutBox->ReportLevel = Status_None;
                OutBox->Host = TranslateIP[ msgI ];
                OutBox->FromName = OutBox->LocalIP;
                OutBox->Port = 6712;
                OutBox->TimeOut = 250;
                OutBox->PostIt( LineChat->Text );
*/
            } catch(...) {
                // nothing...
                 MiniChatList->UserList->Checked[msgI] = false;
                 MiniChat->Lines->Add( ">>>> "+MiniChatList->UserList->Items->Strings[msgI] + " Desconectado ");
            }
        }
    }
    LineChat->Text="";
  }
}
//---------------------------------------------------------------------------

void __fastcall TBoxes::InChatMSG(TComponent *Sender,
      const AnsiString sFrom, const AnsiString sMsg)
{
 for ( int I=0; I < NumUsers; I++ )
 {
   if ( TranslateIP[ I ] == sFrom )
         MiniChatList->UserList->Checked[ I ] = true;
 }

 MiniChat->Lines->Add( TranslateName(sFrom) + "> " + sMsg );
 if ( MiniChat->Lines->Count == 200 ) MiniChat->Lines->Delete( 0 );
}
//---------------------------------------------------------------------------

void __fastcall TBoxes::NewMessageTimer(TObject *Sender)
{
 NewMessage->Enabled = false;
 Visible = true;
 ActiveImage2Click( 0 );
}
//---------------------------------------------------------------------------

void __fastcall TBoxes::AllBoxKeyPress(TObject *Sender, char &Key)
{
  if ( Key == VK_RETURN )
            AllBoxDblClick( 0 );   
}
//---------------------------------------------------------------------------
void __fastcall TBoxes::CoolForm1MouseUp(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
  if ( MiniChat -> Visible )
  {
      MiniChatList->Left = Left + Width;
      MiniChatList->Top  = Top+50;
  }
}
//---------------------------------------------------------------------------



void __fastcall TBoxes::DialUp1ActiveConnection(TObject *Sender,
      int Handle, TRasConnStatusA &Status, AnsiString StatusString,
      AnsiString EntryName, AnsiString DeviceType, AnsiString DeviceName)
{
 DialUp1 -> HangUpConn( Handle );
}
//---------------------------------------------------------------------------

