#include <vdr/remote.h>

#ifndef VDRVERSNUM
#include <vdr/config.h>
#endif

#include "vdr/interface.h"
#include "vdr/status.h"

#include "vdricqosd.h"
#include "icqhook.h"
#include "vdricqsetup.h"
#include "WndTitlebar.h"
#include "WndMessagelist.h"
#include "WndMessage.h"
#include "WndContact.h"
#include "WndStatusbar.h"
 
const char* StatusBitmapFiles[] = { "images/icq_online.xpm",
                                    "images/icq_away.xpm",
                                    "images/icq_na.xpm",
                                    "images/icq_occupied.xpm",
                                    "images/icq_dnd.xpm",
                                    "images/icq_freeforchat.xpm",
                                    "images/icq_offline.xpm",
                                    "images/icq_invisible.xpm",
                                   };


// ----------- cVdrIcqOsd ---------------------------------------------------------------

cMutex cVdrIcqOsd::OsdMutex;

cVdrIcqOsd::cVdrIcqOsd(SimpleClient *pIcqClient) 
{
  m_pOsd            = NULL;
  m_pTitlebarWnd    = NULL;
  m_pMessagelistWnd = NULL;
  m_pMessageWnd     = NULL;
  m_pContactWnd     = NULL;
  m_pStatusbarWnd   = NULL;
  m_pIcqClient      = pIcqClient; 
  m_bRunning        = true;
  m_bShutdown       = false;
  m_eSelectedWindow = swMessage;
  m_eLastSelectedWindow = swMessage;
  m_LastKey             = kNone;
  m_bWaiting            = false;
  m_bInterrupted        = false;
  for (int i = 0; i < STATUSCOUNT; i++ )
  {
    char *bitmapfile;
    pStatusBitmaps[i] = new cBitmap(15, 15, 4);
    asprintf(&bitmapfile, "%s/%s", cPlugin::ConfigDirectory("vdricq"), StatusBitmapFiles[i]);
    if (!pStatusBitmaps[i]->LoadXpm(bitmapfile))
      esyslog("vdricq: Cannot load Statusimage %s", bitmapfile);
    free(bitmapfile);
  }
  Start();
}
 
cVdrIcqOsd::~cVdrIcqOsd(void) 
{
  if (VdrIcqSetup.StatusOnCloseVdrICQ < 7)
    m_pIcqClient->SetStatus((ICQ2000::Status)VdrIcqSetup.StatusOnCloseVdrICQ);
  else if (VdrIcqSetup.StatusOnCloseVdrICQ == 7)
    m_pIcqClient->SetStatus(ICQ2000::STATUS_ONLINE, true);

  m_bRunning = false;
  while (!m_bShutdown)
  {
    usleep(100);
  }

  m_pIcqClient->SetTitlebarWnd(NULL);
  m_pIcqClient->SetMessagelistWnd(NULL);
  m_pIcqClient->SetContactWnd(NULL);
  m_pIcqClient->SetStatusbarWnd(NULL);

  delete m_pStatusbarWnd;
  delete m_pContactWnd;
  delete m_pMessageWnd;
  delete m_pMessagelistWnd;
  delete m_pTitlebarWnd;
  delete m_pOsd;
  for (int i = 0; i < 8; i++ )
    delete pStatusBitmaps[i];
}

eOSState cVdrIcqOsd::ProcessKey(eKeys Key) 
{
  if (m_pStatusbarWnd->WaitForConfirming())
  {
    cRemote::Put(Key);
    return osContinue;
  }

  eOSState state = cOsdObject::ProcessKey(Key);
  if (state == osUnknown) 
  {
    if ((m_pMessagelistWnd->ForegroundMessageVisible()) && (Key != kNone))
      m_pMessagelistWnd->HiddeForegroundMessage();

    if (((Key == kRed) || (Key == kGreen) || (Key == kYellow) || (Key == kBlue) || (Key == kBack)) &&
        (m_pStatusbarWnd->IsDefaulMenu()))
    {
      switch (Key)
      {
      case kRed:
        SetSelectedWindow(swMessage);
        break;

      case kGreen:
        SetSelectedWindow(swMessageList);
        break;
        
      case kYellow:
        SetSelectedWindow(swContact);
        break;
       
      case kBlue:
        SetSelectedWindow(swTitlebar);
        break;

      case kBack:
        return osEnd;
        break;
       
      default:
        break;
      }

      if (m_eSelectedWindow == swTitlebar)
      {
        m_pOsd->GetBitmap(1)->Reset();
        m_pTitlebarWnd->Draw();
      }
      else
      {
        m_pOsd->GetBitmap(2)->Reset();
        m_pOsd->GetBitmap(3)->Reset();
        m_pOsd->GetBitmap(4)->Reset();
        m_pMessageWnd->Draw();
        m_pMessagelistWnd->Draw();
        m_pContactWnd->Draw();
        //m_pStatusbarWnd->ShowDefaultButtons();
      }

      return osContinue;
    }

    
    switch (m_eSelectedWindow)
    {
    case swTitlebar:
      if (Key != kNone)
        state = m_pTitlebarWnd->ProcessKey(Key);
      break;

    case swMessage:
      if (Key != kNone)
        state = m_pMessageWnd->ProcessKey(Key);
      break;

    case swMessageList:
      if (Key != kNone)
        state = m_pMessagelistWnd->ProcessKey(Key);
      break;

    case swContact:
      if (Key != kNone)
        state = m_pContactWnd->ProcessKey(Key);
      break;

    default:
      break;
    }
  }


  return osContinue;
}

void cVdrIcqOsd::Show() 
{
  m_pOsd = (cOsd*)cOsdProvider::NewOsd(VdrIcqSetup.OriginX, VdrIcqSetup.OriginY);  
  if (m_pOsd) 
  {
    m_pTitlebarWnd    = new cTitlebarWnd    (0,   0,    624,  27,   1,  m_pOsd, this, m_pIcqClient);
    m_pStatusbarWnd   = new cStatusbarWnd   (0,   460,  624,  27,   2,  m_pOsd, this);
    m_pMessagelistWnd = new cMessagelistWnd (6,   32,   460,  382,  2,  m_pOsd, this, m_pIcqClient,
      m_pStatusbarWnd);
    m_pMessageWnd     = new cMessageWnd     (6,   416,  460,  31,   2,  m_pOsd, this, m_pIcqClient, 
      m_pMessagelistWnd, m_pStatusbarWnd);
    m_pContactWnd     = new cContactWnd     (482, 32,   128,  415,  4,  m_pOsd, this, m_pIcqClient,
      m_pStatusbarWnd);

    m_pTitlebarWnd->SetStatusbarWnd(m_pStatusbarWnd);

    tArea Areas[] = { m_pTitlebarWnd->GetArea1(),
                      m_pTitlebarWnd->GetArea2(),
                      {m_pMessagelistWnd->GetArea1().x1, m_pMessagelistWnd->GetArea1().y1,
                       m_pMessagelistWnd->GetArea1().x2, m_pMessageWnd->GetArea().y2, 4},
                      {m_pMessagelistWnd->GetArea2().x1, m_pMessagelistWnd->GetArea2().y1,
                       m_pMessagelistWnd->GetArea2().x2, m_pMessageWnd->GetArea().y2, 2},
                      m_pContactWnd->GetArea(),
                      m_pStatusbarWnd->GetArea1(),
                      m_pStatusbarWnd->GetArea2()
                    };
    m_pOsd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));

    m_pIcqClient->SetTitlebarWnd(m_pTitlebarWnd);
    m_pIcqClient->SetMessagelistWnd(m_pMessagelistWnd);
    m_pIcqClient->SetContactWnd(m_pContactWnd);
    m_pIcqClient->SetStatusbarWnd(m_pStatusbarWnd);
    
    DrawMenu();
  } 

  if (VdrIcqSetup.StatusOnOpenVdrICQ < 7)
    m_pIcqClient->SetStatus((ICQ2000::Status)VdrIcqSetup.StatusOnOpenVdrICQ);
  else if (VdrIcqSetup.StatusOnOpenVdrICQ == 7)
    m_pIcqClient->SetStatus(ICQ2000::STATUS_ONLINE, true);
}

void cVdrIcqOsd::Action()
{
  while(m_bRunning)
  {
    if (m_pTitlebarWnd)
      m_pTitlebarWnd->Takt();

    usleep(1000000);
  }

  m_bShutdown = true;
}
 

void cVdrIcqOsd::ClearBitmap() 
{
  cMutexLock lock(&cVdrIcqOsd::OsdMutex);
  m_pOsd->GetBitmap(0)->Reset();
  m_pOsd->GetBitmap(1)->Reset();
  m_pOsd->GetBitmap(2)->Reset();
  m_pOsd->GetBitmap(3)->Reset();
  m_pOsd->GetBitmap(4)->Reset();
  m_pOsd->GetBitmap(5)->Reset();
  m_pOsd->GetBitmap(6)->Reset();
}

void cVdrIcqOsd::DrawMenu() 
{
  ClearBitmap();

  m_pTitlebarWnd->SetTitleColors(clrBlack, clrCyan);
  m_pTitlebarWnd->SetTitleText("VDR-ICQ");
  DrawTitlebarWnd();
  DrawMessagelistWnd();
  DrawMessageWnd();
  DrawContactWnd();
  m_pStatusbarWnd->ShowDefaultButtons();
}

void cVdrIcqOsd::SetSelectedWindow(ESelectedWindow eSelectedWindow) 
{ 
  m_eLastSelectedWindow = m_eSelectedWindow; 
  m_eSelectedWindow = eSelectedWindow; 
}

eKeys cVdrIcqOsd::Wait(int Seconds, bool KeepChar /*= false*/)
{
  m_LastKey      = kNone;
  m_bInterrupted = false;
  m_bWaiting     = true;

  if (Seconds == 0)
     Seconds = Setup.OSDMessageTime;
  time_t timeout = time(NULL) + Seconds;
  for (;;) 
  {
    if ((m_LastKey != kNone && (RAWKEY(m_LastKey) != kOk || RAWKEY(m_LastKey) == m_LastKey)) || 
         time(NULL) > timeout || m_bInterrupted)
      break;
    usleep(100000);
  }

  m_bWaiting = false;

  return m_LastKey;
}


void cVdrIcqOsd::DrawTitlebarWnd()
{ 
  if (m_pTitlebarWnd)     
    m_pTitlebarWnd->Draw(); 
}


void cVdrIcqOsd::DrawMessagelistWnd()
{ 
  if (m_pMessagelistWnd)  
    m_pMessagelistWnd->Draw(); 
}


void cVdrIcqOsd::DrawMessageWnd()
{ 
  if (m_pMessageWnd) 
    m_pMessageWnd->Draw(); 
}


void cVdrIcqOsd::DrawContactWnd()
{ 
  if (m_pContactWnd)      
    m_pContactWnd->Draw(); 
}
