#include "WndMessagelist.h"
#include "vdricqosd.h"
#include "icqhook.h"
#include "WndStatusbar.h"


// ----------- cMessagelistWnd ----------------------------------------------------------

cMessagelistWnd::cMessagelistWnd(int iLeft, int iTop, int iWidth, int iHeight, int iBpP, cOsd *pOsd,
                                 cVdrIcqOsd *pVdrIcqOsd, SimpleClient *pIcqClient, cStatusbarWnd *pStatusbarWnd)
{
  tArea Area    = { iLeft, iTop, iLeft + iWidth - 1, iTop + iHeight - 1, iBpP };
  m_Area1       = Area;
  m_Area2       = Area;
  m_Area1.x2    = 101;
  m_Area1.bpp   = 4;
  m_Area2.x1    = 102;
  m_pOsd        = pOsd;
  m_pMessageQueue = NULL;
  m_iScrolldiff   = 0;
  m_pVdrIcqOsd    = pVdrIcqOsd;
  m_pIcqClient    = pIcqClient;
  m_pStatusbarWnd = pStatusbarWnd;
  m_boolLastRowVisible     = true;
  m_bShowForegroundMessage = false;
}

cMessagelistWnd::~cMessagelistWnd()
{
}

tArea cMessagelistWnd::GetArea1(void)
{
  return m_Area1;
}

tArea cMessagelistWnd::GetArea2(void)
{
  return m_Area2;
}

eOSState cMessagelistWnd::ProcessKey(eKeys Key)
{
  switch (Key) 
  {
  case kUp:
    SetHelpKeys();
  case kUp|k_Repeat:
  if (!m_boolLastRowVisible)
    {
      m_iScrolldiff++;
      Draw();
    }
    break;

  case kDown:
    SetHelpKeys();
  case kDown|k_Repeat:
    if (m_iScrolldiff > 0)
    {
      m_iScrolldiff--;
      Draw();
    }
    break;

  case kBack:
    m_pStatusbarWnd->ShowDefaultButtons();
    return osContinue;
    break;

  default:
    break;
  }

  return osContinue;
}


void cMessagelistWnd::Draw(void)
{
  if ((m_pOsd->GetBitmap(0) == NULL) || (m_bShowForegroundMessage))
    return; 

  { // start Mutex section
    cMutexLock lock(&cVdrIcqOsd::OsdMutex);

    if (m_pVdrIcqOsd->GetSelectedWindow() == swMessageList)
    {
      m_pOsd->DrawRectangle(m_Area1.x1, m_Area1.y1, m_Area2.x2, m_Area2.y2, clrRed);
    }
    else
    {
      m_pOsd->DrawRectangle(m_Area1.x1, m_Area1.y1, m_Area2.x2, m_Area2.y2, clrBlue);
    }
    m_pOsd->DrawRectangle(m_Area1.x1 + 2, m_Area1.y1 + 2, m_Area2.x2 - 2, m_Area2.y2 - 2, clrGray50);
    
    if (m_pMessageQueue == NULL)
    {
      esyslog("vdricq: cMessagelistWnd::Draw() m_pMessageQueue = NULL");
      return;
    }

    ICQ2000::ContactRef Contact = m_pIcqClient->GetActiveContact();
    int iYPos = m_Area1.y2 - LINEHEIGHT - 1;
    int iSize = m_pMessageQueue->get_contact_size(Contact);
    m_boolLastRowVisible = true;
    int iVisibleMessages = 0;
    for (int iPos = iSize - 1 - m_iScrolldiff; (iPos >= 0) && (iYPos > m_Area1.y1); iPos--)
    {
      string message;
      MessageEvent *ev = m_pMessageQueue->get_contact_message_at(Contact, iPos);
      time_t Time = ev->getTime();
      struct tm *tm = localtime(&Time);
      char time_str[256];
      strftime(time_str, 255, "[%H:%M] ", tm);

      if (((ICQMessageEvent*)ev)->getICQMessageType() == ICQMessageEvent::Normal) 
      {
        NormalICQMessageEvent *nev = static_cast<NormalICQMessageEvent*>(ev);
        if (nev->IsMyMessage())
        {
          ICQ2000::ContactRef MyContact = m_pIcqClient->GetSelfContact();
          message = time_str + MyContact->getNameAlias() + ": " + nev->getMessage();
        }
        else
        {
          message = time_str + Contact->getNameAlias() + ": " + nev->getMessage();
        }
      }
      
      // Zeilenumbrueche einfuegen
      ZeilenumbruecheEinfuegen(message);

      unsigned int PosZaehler = 0;
      int ZeilenAnz = 0;
      while (PosZaehler < message.size())
      {
        PosZaehler = message.find("\n", PosZaehler) + 1;
        ZeilenAnz++;
      }
      
      iYPos -= (ZeilenAnz-1) * LINEHEIGHT;

      PosZaehler = 0;
      unsigned int OldPos = 0;
      ZeilenAnz = 0;
      string teilmsg1;
      while (PosZaehler < message.size())
      {
        PosZaehler = message.find("\n", PosZaehler);
        teilmsg1 = message.substr(OldPos, PosZaehler - OldPos);
        if (iYPos + (ZeilenAnz * LINEHEIGHT) > m_Area1.y1)
        {
          m_pOsd->DrawText(m_Area1.x1 + 3, iYPos + (ZeilenAnz * LINEHEIGHT), teilmsg1.c_str(), 
            clrWhite, clrGray50, font);
        }
        else
        {
          m_boolLastRowVisible = false;
        }
        OldPos = PosZaehler;
        PosZaehler++;
        ZeilenAnz++;
      }
      iYPos -= LINEHEIGHT;
      iVisibleMessages++;
    }

    if (iYPos <= m_Area1.y1)
    {
      m_boolLastRowVisible = false;
    }

    int iScrollbarHeight = m_Area2.Height();
    if (iSize > 0)
    {
      int iScrollbarHeight = m_Area2.Height() * iVisibleMessages / iSize;
      if (iScrollbarHeight < 20)
        iScrollbarHeight = 20;
    }
    int iScrollHeight = m_Area2.Height() - iScrollbarHeight;
    int iScrollMessages = iSize - (m_Area2.Height() / LINEHEIGHT);
    int iScrollPos = 0;
    if (iScrollMessages > 0)
      iScrollPos = iScrollHeight * m_iScrolldiff / iScrollMessages;

    if (m_pVdrIcqOsd->GetSelectedWindow() == swMessageList)
    {
      m_pOsd->DrawRectangle(m_Area2.x2 - 5, m_Area2.y2 - iScrollPos - iScrollbarHeight, 
        m_Area2.x2, m_Area2.y2 - iScrollPos, clrRed);
      m_pOsd->DrawRectangle(m_Area2.x2 - 5, m_Area2.y1, m_Area2.x2 - 5, m_Area2.y2, clrRed);
    }
    else
    {
      m_pOsd->DrawRectangle(m_Area2.x2 - 5, m_Area2.y2 - iScrollPos - iScrollbarHeight, 
        m_Area2.x2, m_Area2.y2 - iScrollPos, clrBlue);
      m_pOsd->DrawRectangle(m_Area2.x2 - 5, m_Area2.y1, m_Area2.x2 - 5, m_Area2.y2, clrBlue);
    }

    m_pOsd->Flush();
  } // end Mutex section

  if (m_pVdrIcqOsd->GetSelectedWindow() == swMessageList)
    SetHelpKeys();
}

void cMessagelistWnd::SetMessageList(MessageQueue *pMessageQueue)
{
  m_pMessageQueue = pMessageQueue;
}

void cMessagelistWnd::Clear(void)
{
}

void cMessagelistWnd::ShowContactDetails(ICQ2000::ContactRef c)
{
  if (m_pOsd->GetBitmap(0) == NULL)
    return; 
  
  cMutexLock lock(&cVdrIcqOsd::OsdMutex);

  m_bShowForegroundMessage = true;

  const char* GENDER[] = { "No Specified", "Female", "Male" };
  ICQ2000::Contact::MainHomeInfo MHInfo = c->getMainHomeInfo();
  ICQ2000::Contact::HomepageInfo HpInfo = c->getHomepageInfo();
  string tempStr;
  char tempStr2[100];


  m_pOsd->DrawRectangle(m_Area1.x1, m_Area1.y1, m_Area2.x2, m_Area2.y2, clrBlue);
  m_pOsd->DrawRectangle(m_Area1.x1 + 2, m_Area1.y1 + 2, m_Area2.x2 - 2, m_Area2.y2 - 2, clrGray50);

  m_pOsd->DrawText(m_Area1.x1 + 10, m_Area1.y1 + 10,    tr("ICQ-Nr:"),             clrWhite, clrGray50, font);
  m_pOsd->DrawText(m_Area1.x1 + 10, m_Area1.y1 + 40,    tr("NickName:"),           clrWhite, clrGray50, font);
  m_pOsd->DrawText(m_Area1.x1 + 10, m_Area1.y1 + 70,    tr("Name:"),               clrWhite, clrGray50, font);
  m_pOsd->DrawText(m_Area1.x1 + 10, m_Area1.y1 + 100,   tr("Adress:"),             clrWhite, clrGray50, font);
  m_pOsd->DrawText(m_Area1.x1 + 10, m_Area1.y1 + 130,   tr("Gender:"),             clrWhite, clrGray50, font);
  m_pOsd->DrawText(m_Area1.x1 + 10, m_Area1.y1 + 160,   tr("Birth Date:"),         clrWhite, clrGray50, font);
  m_pOsd->DrawText(m_Area1.x1 + 10, m_Area1.y1 + 190,   tr("Age:"),                clrWhite, clrGray50, font);
  m_pOsd->DrawText(m_Area1.x1 + 10, m_Area1.y1 + 220,   tr("Language:"),           clrWhite, clrGray50, font);
  m_pOsd->DrawText(m_Area1.x1 + 10, m_Area1.y1 + 250,   tr("Mobile:"),             clrWhite, clrGray50, font);
  m_pOsd->DrawText(m_Area1.x1 + 10, m_Area1.y1 + 280,   tr("eMail:"),              clrWhite, clrGray50, font);
  m_pOsd->DrawText(m_Area1.x1 + 10, m_Area1.y1 + 310,   tr("Homepage:"),           clrWhite, clrGray50, font);

  m_pOsd->DrawText(m_Area1.x1 + 135, m_Area1.y1 + 10,  c->getStringUIN().c_str(),  clrWhite, clrGray50, font);
  m_pOsd->DrawText(m_Area1.x1 + 135, m_Area1.y1 + 40,   c->getAlias().c_str(),     clrWhite, clrGray50, font);
  tempStr = c->getFirstName() + (string)" " + c->getLastName();
  m_pOsd->DrawText(m_Area1.x1 + 135, m_Area1.y1 + 70,  tempStr.c_str(),            clrWhite, clrGray50, font);
  tempStr = MHInfo.state + ", " + MHInfo.city;
  m_pOsd->DrawText(m_Area1.x1 + 135, m_Area1.y1 + 100,  tempStr.c_str(),           clrWhite, clrGray50, font);
  m_pOsd->DrawText(m_Area1.x1 + 135, m_Area1.y1 + 130, tr(GENDER[HpInfo.sex]),     clrWhite, clrGray50, font);
  sprintf(tempStr2, "%02d.%02d.%04d", HpInfo.birth_month, HpInfo.birth_day, HpInfo.birth_year);
  m_pOsd->DrawText(m_Area1.x1 + 135, m_Area1.y1 + 160, tempStr2,                   clrWhite, clrGray50, font);
  sprintf(tempStr2, "%d", HpInfo.age);
  m_pOsd->DrawText(m_Area1.x1 + 135, m_Area1.y1 + 190, tempStr2,                   clrWhite, clrGray50, font);
  tempStr = "";
  if (HpInfo.getLanguage(2) != (string)"Unspecified")
    tempStr = HpInfo.getLanguage(1);
  if (HpInfo.getLanguage(2) != (string)"Unspecified")
  {
    if (tempStr.length() > 0)
      tempStr += ", ";
    tempStr += HpInfo.getLanguage(2);
  }
  if (HpInfo.getLanguage(3) != (string)"Unspecified")
  {
    if (tempStr.length() > 0)
      tempStr += ", ";
    tempStr += HpInfo.getLanguage(3);
  }
  if (m_Area1.x1 + 135 + smlfont->Width(tempStr.c_str()) + 10 < m_Area2.x2)
  {
    m_pOsd->DrawText(m_Area1.x1 + 135, m_Area1.y1 + 220, tempStr.c_str(),          clrWhite, clrGray50, font);
  }
  else
  {
    m_pOsd->DrawText(m_Area1.x1 + 135, m_Area1.y1 + 220, tempStr.c_str(),          clrWhite, clrGray50, smlfont);
  }
  m_pOsd->DrawText(m_Area1.x1 + 135, m_Area1.y1 + 250, c->getMobileNo().c_str(),   clrWhite, clrGray50, font);
  m_pOsd->DrawText(m_Area1.x1 + 135, m_Area1.y1 + 280, c->getEmail().c_str(),      clrWhite, clrGray50, font);
  if (m_Area1.x1 + 135 + font->Width(HpInfo.homepage.c_str()) + 10 < m_Area2.x2)
  {
    m_pOsd->DrawText(m_Area1.x1 + 135, m_Area1.y1 + 310, HpInfo.homepage.c_str(),  clrWhite, clrGray50, font);
  }
  else if (m_Area1.x1 + 135 + smlfont->Width(HpInfo.homepage.c_str()) + 10 < m_Area2.x2)
  {
    m_pOsd->DrawText(m_Area1.x1 + 135, m_Area1.y1 + 315, HpInfo.homepage.c_str(),  clrWhite, clrGray50, smlfont);
  }
  else
  {
    string homepage = HpInfo.homepage.c_str();
    int iTop = m_Area1.y1 + 310;
    while(homepage.length() > 0)
    {
      unsigned int iPos = 1;
      while ((m_Area1.x1 + 135 + smlfont->Width(homepage.substr(0, iPos).c_str()) + 10 < m_Area2.x2) && 
             (iPos < homepage.length()))
      {
        iPos++;
      }
      if (iPos < homepage.length())
       iPos--;
      tempStr = homepage.substr(0, iPos);
      homepage = homepage.substr(iPos, homepage.length() - iPos);
      m_pOsd->DrawText(m_Area1.x1 + 135, iTop, tempStr.c_str(),  clrWhite, clrGray50, smlfont);
      iTop += smlfont->Height();
    }
  }

  m_pOsd->Flush();
}


void cMessagelistWnd::ShowMessage(std::string sMessage)
{
  if (m_pOsd->GetBitmap(0) == NULL)
    return; 

  cMutexLock lock(&cVdrIcqOsd::OsdMutex);
  m_bShowForegroundMessage = true;

  ZeilenumbruecheEinfuegen(sMessage);

  m_pOsd->DrawRectangle(m_Area1.x1, m_Area1.y1, m_Area2.x2, m_Area2.y2, clrBlue);
  m_pOsd->DrawRectangle(m_Area1.x1 + 2, m_Area1.y1 + 2, m_Area2.x2 - 2, m_Area2.y2 - 2, clrGray50);

  int PosZaehler = 0;
  int OldPos = 0;
  int ZeilenAnz = 0;
  string teilmsg1;
  while (PosZaehler < (int)sMessage.size())
  {
    PosZaehler = sMessage.find("\n", PosZaehler);
    teilmsg1 = sMessage.substr(OldPos, PosZaehler - OldPos);

    m_pOsd->DrawText(m_Area1.x1 + 10, m_Area1.y1 + 10 + (ZeilenAnz * LINEHEIGHT), teilmsg1.c_str(), 
      clrWhite, clrGray50, font);
    
    OldPos = PosZaehler;
    PosZaehler++;
    ZeilenAnz++;
  }

  m_pOsd->Flush();
}


void cMessagelistWnd::HiddeForegroundMessage(void)
{
  m_bShowForegroundMessage = false;
  Draw();
}

void cMessagelistWnd::ZeilenumbruecheEinfuegen(std::string &message)
{
  unsigned int OldPos = 0, PosZaehler = 0;
  while (PosZaehler < message.size())
  {
    string teilmsg1, teilmsg2;
    int LeerAnz = 0;
    if (PosZaehler > 0)
    {
      message.insert(PosZaehler, "  ");
      PosZaehler += 2;
    }
    while ((font->Width((teilmsg1 + teilmsg2).c_str()) < m_Area2.x2 - m_Area1.x1 - 10) && 
           (PosZaehler < message.size()))
    {
      teilmsg1 = teilmsg1 + teilmsg2;
      int pos1 = message.find(" ", PosZaehler);
      int pos2 = message.find("\n", PosZaehler);
              
      if (pos1 == -1)
        PosZaehler = message.size();
      else
        PosZaehler = pos1 + 1;

      if ((pos2 < (int)PosZaehler) && (pos2 > -1))
        PosZaehler = pos2 + 1;

      teilmsg2 = message.substr(OldPos, PosZaehler - OldPos);
      OldPos = PosZaehler;
      LeerAnz++;
    }
    if ((font->Width((teilmsg1 + teilmsg2).c_str()) >= m_Area2.x2 - m_Area1.x1 - 10))
    {
      PosZaehler -= teilmsg2.size();
      OldPos = PosZaehler;
      if (LeerAnz == 1)
      {
        PosZaehler++;
        teilmsg1 = "";
        while ((font->Width(teilmsg1.c_str()) < m_Area2.x2 - m_Area1.x1 - 40) && 
               (PosZaehler < message.size()))
        {
          teilmsg1 = message.substr(OldPos, PosZaehler - OldPos);
          PosZaehler++;
        }
      }
      OldPos = PosZaehler;
    }
    message.insert( PosZaehler ++, "\n");
  }
}


void cMessagelistWnd::SetHelpKeys(void)
{
  m_pStatusbarWnd->ShowDefaultButtons();
}
