/***************************************************************************
                          kmymoneyscheduleddatetbl.cpp  -  description
                             -------------------
    begin                : Thu Jul 3 2003
    copyright            : (C) 2000-2003 by Michael Edwardes
    email                : mte@users.sourceforge.net
                           Javier Campos Morales <javi_c@users.sourceforge.net>
                           Felix Rodriguez <frodriguez@users.sourceforge.net>
                           John C <thetacoturtle@users.sourceforge.net>
                           Thomas Baumgart <ipwizard@users.sourceforge.net>
                           Kevin Tambascio <ktambascio@users.sourceforge.net>
 ***************************************************************************/
 /****************************************************************************
 Contains code from the KDateTable class ala tdelibs-3.1.2.  Original license:

    This file is part of the KDE libraries
    Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org)
              (C) 1998-2001 Mirko Boehm (mirko@kde.org)
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/
/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

// ----------------------------------------------------------------------------
// QT Includes
#include <tqstring.h>
#include <tqpen.h>
#include <tqpainter.h>
#include <tqdialog.h>
#include <tqdrawutil.h>
#include <tqcursor.h>
#include <tqapplication.h>

// ----------------------------------------------------------------------------
// KDE Includes
#include "kdecompat.h"
#include <tdeglobal.h>
#include <tdeglobalsettings.h>
#include <tdelocale.h>

// ----------------------------------------------------------------------------
// Project Includes
#include "kmymoneyscheduleddatetbl.h"
#include "../mymoney/mymoneyfile.h"

kMyMoneyScheduledDateTbl::kMyMoneyScheduledDateTbl(TQWidget *parent, TQDate date_, const char* name, WFlags f )
  : kMyMoneyDateTbl(parent, date_, name, f),
  m_filterBills(false), m_filterDeposits(false), m_filterTransfers(false)
{
  connect(&briefWidget, TQT_SIGNAL(enterClicked(const MyMoneySchedule&, const TQDate&)), this, TQT_SIGNAL(enterClicked(const MyMoneySchedule&, const TQDate&)));
  connect(&briefWidget, TQT_SIGNAL(skipClicked(const MyMoneySchedule&, const TQDate&)), this, TQT_SIGNAL(skipClicked(const MyMoneySchedule&, const TQDate&)));
}

kMyMoneyScheduledDateTbl::~kMyMoneyScheduledDateTbl()
{
}

void kMyMoneyScheduledDateTbl::drawCellContents(TQPainter *painter, int /*row*/, int /*col*/, const TQDate& theDate)
{
  TQRect rect;
  TQString text;
  int w=cellWidth();
  int h=cellHeight();
  TQPen pen;
  TQBrush brushBlue(TDEGlobalSettings::activeTitleColor());
  TQBrush brushLightblue(TDEGlobalSettings::baseColor());
  TQFont font=TDEGlobalSettings::generalFont();
  MyMoneyFile *file = MyMoneyFile::instance();

  // -----
  font.setPointSize(fontsize);
  TQFont fontLarge(font);
  TQFont fontSmall(font);
  fontLarge.setPointSize(fontsize*2);
  fontSmall.setPointSize(fontsize-1);

  painter->setFont(font);


  if (m_type == MONTHLY)
  {
    if (theDate.month() != date.month())
    {
      painter->setFont(fontSmall);
      pen = TQPen(lightGray);
    }
    else
    {
      pen = TQPen(gray);
    }

    if (theDate == date)
    {
      if (hasFocus())
      { // draw the currently selected date
        painter->setPen(TDEGlobalSettings::highlightColor());
        painter->setBrush(TDEGlobalSettings::highlightColor());
        pen=TQPen(white);
      } else {
        painter->setPen(TDEGlobalSettings::calculateAlternateBackgroundColor(TDEGlobalSettings::highlightColor()));
        painter->setBrush(TDEGlobalSettings::calculateAlternateBackgroundColor(TDEGlobalSettings::highlightColor()));
        pen=TQPen(white);
      }
    } else {
      painter->setBrush(TDEGlobalSettings::baseColor());
      painter->setPen(TDEGlobalSettings::baseColor());
    }
    painter->drawRect(0, 0, w, h);
    painter->setPen(pen);
    text = TQString::number(theDate.day());
    addDayPostfix(text);
    painter->drawText(0, 0, w-2, h, AlignRight, text, -1, &rect);

    MyMoneyFile *file = MyMoneyFile::instance();
    TQValueList<MyMoneySchedule> schedules;
    try
    {

      // Honour the filter.
      int scheduleTypes=0;
      int scheduleOcurrences=0;
      int schedulePaymentTypes=0;

      scheduleOcurrences |= MyMoneySchedule::OCCUR_ANY;
      schedulePaymentTypes |= MyMoneySchedule::STYPE_ANY;

      if (!m_filterBills)
      {
        scheduleTypes |= MyMoneySchedule::TYPE_BILL;
      }
      if (!m_filterDeposits)
      {
        scheduleTypes |= MyMoneySchedule::TYPE_DEPOSIT;
      }
      if (!m_filterTransfers)
      {
        scheduleTypes |= MyMoneySchedule::TYPE_TRANSFER;
      }

      schedules = file->scheduleListEx( scheduleTypes,
                                        scheduleOcurrences,
                                        schedulePaymentTypes,
                                        theDate,
                                        m_filterAccounts);
    }
    catch ( MyMoneyException* e)
    {
      // SAfe to ignore here, cause no schedules might exist
      // for the selected account
      delete e;
    }

    if (schedules.count() >= 1)
    {
      TQValueList<MyMoneySchedule>::Iterator iter;
      bool anyOverdue=false;
      for (iter=schedules.begin(); iter!=schedules.end(); ++iter)
      {
        MyMoneySchedule schedule = *iter;
        if (theDate < TQDate::currentDate())
        {
          if (schedule.isOverdue())
          {
            anyOverdue = true;
            break; // out early
          }
        }
      }

      if (anyOverdue)
        painter->setPen(red);
      else
        painter->setPen(darkGray);

      painter->setFont(fontLarge);
      painter->drawText(0, 0, w, h, AlignCenter, TQString::number(schedules.count()),
          -1, &rect);
    }

    painter->setPen(lightGray);
    painter->setBrush(TQt::NoBrush);
    painter->drawRect(0, 0, w, h);
  }
  else if (m_type == WEEKLY)
  {
    // TODO: Handle other start weekdays than Monday
    if (theDate == date)
    {
      painter->setBrush(TDEGlobalSettings::highlightColor());
    }
    else
    {
      painter->setBrush(TDEGlobalSettings::baseColor());
      painter->setPen(TDEGlobalSettings::baseColor());
    }

    painter->setPen(lightGray);
    painter->drawRect(0, 0, w, h);

    text = TQString::number(theDate.day());
    addDayPostfix(text);

    painter->drawText(0, 0, w-2, h, AlignRight, TQDate::shortDayName(theDate.dayOfWeek()) + " " + text, -1, &rect);

    TQValueList<MyMoneySchedule> billSchedules;
    TQValueList<MyMoneySchedule> depositSchedules;
    TQValueList<MyMoneySchedule> transferSchedules;
    try
    {
      text = TQString();

      if (!m_filterBills)
      {
        billSchedules = file->scheduleListEx( MyMoneySchedule::TYPE_BILL,
                                          MyMoneySchedule::OCCUR_ANY,
                                          MyMoneySchedule::STYPE_ANY,
                                          theDate,
                                          m_filterAccounts);

        if (billSchedules.count() >= 1)
        {
          text += i18n("%1 Bills.").arg(TQString::number(billSchedules.count()));
        }
      }

      if (!m_filterDeposits)
      {
        depositSchedules = file->scheduleListEx( MyMoneySchedule::TYPE_DEPOSIT,
                                          MyMoneySchedule::OCCUR_ANY,
                                          MyMoneySchedule::STYPE_ANY,
                                          theDate,
                                          m_filterAccounts);

        if (depositSchedules.count() >= 1)
        {
          if(!text.isEmpty())
            text += "  ";
          text += i18n("%1 Deposits.").arg(TQString::number(depositSchedules.count()));
        }
      }

      if (!m_filterTransfers)
      {
        transferSchedules = file->scheduleListEx( MyMoneySchedule::TYPE_TRANSFER,
                                          MyMoneySchedule::OCCUR_ANY,
                                          MyMoneySchedule::STYPE_ANY,
                                          theDate,
                                          m_filterAccounts);

        if (transferSchedules.count() >= 1)
        {
          if(!text.isEmpty())
            text += "  ";
          text += i18n("%1 Transfers.").arg(TQString::number(transferSchedules.count()));
        }
      }
    }
    catch (MyMoneyException* e)
    {
      // SAfe to ignore here, cause no schedules might exist
      // for the selected account
      delete e;
    }

    bool anyOverdue=false;
    TQValueList<MyMoneySchedule>::Iterator iter;
    for (iter=transferSchedules.begin(); iter!=transferSchedules.end(); ++iter)
    {
      MyMoneySchedule schedule = *iter;
      if (theDate < TQDate::currentDate())
      {
        if (schedule.isOverdue())
        {
          anyOverdue = true;
          break; // out early
        }
      }
    }

    if (!anyOverdue)
    {
      for (iter=depositSchedules.begin(); iter!=depositSchedules.end(); ++iter)
      {
        MyMoneySchedule schedule = *iter;
        if (theDate < TQDate::currentDate())
        {
          if (schedule.isOverdue())
          {
            anyOverdue = true;
            break; // out early
          }
        }
      }

      if (!anyOverdue)
      {
        for (iter=billSchedules.begin(); iter!=billSchedules.end(); ++iter)
        {
          MyMoneySchedule schedule = *iter;
          if (theDate < TQDate::currentDate())
          {
            if (schedule.isOverdue())
            {
              anyOverdue = true;
              break; // out early
            }
          }
        }
      }
    }

    if (anyOverdue)
      painter->setPen(red);
    else
      painter->setPen(darkGray);

    painter->setFont(fontLarge);
    painter->drawText(0, 0, w, h, AlignCenter, text,
          -1, &rect);
  }
  else if (m_type == QUARTERLY)
  {
    painter->setBrush(TDEGlobalSettings::baseColor());

    painter->setPen(lightGray);
    painter->drawRect(0, 0, w, h);
  }
}

void kMyMoneyScheduledDateTbl::addDayPostfix(TQString& text)
{
  int d = text.toInt();

  if (d >= 1 && d <= 31)
  {
    TQStringList postfixList = TQStringList::split("-", i18n("st-nd-rd-th-th-th-th-th-th-th-th-th-th-th-th-th-th-th-th-th-st-nd-rd-th-th-th-th-th-th-th-st"), true);
    text += postfixList[d-1];
  }
}

void kMyMoneyScheduledDateTbl::refresh()
{
  repaintContents(false);
}

void kMyMoneyScheduledDateTbl::contentsMouseMoveEvent(TQMouseEvent* e)
{
  int row, col, pos;
  TQPoint mouseCoord;

  if (isActiveWindow() || briefWidget.isVisible())
  {
    mouseCoord = e->pos();
    row = rowAt(mouseCoord.y());
    col = columnAt(mouseCoord.x());
    if (row<1 || col<0)
    {
      return;
    }

  #if TDE_VERSION < 310
    int firstWeekDay = TDEGlobal::locale()->weekStartsMonday() ? 1 : 0;
  #else
    int firstWeekDay = TDEGlobal::locale()->weekStartDay();
  #endif

    TQDate drawDate(date);
    TQString text;

    if (m_type == MONTHLY)
    {
      pos=7*(row-1)+col;
      if ( firstWeekDay < 4 )
        pos += firstWeekDay;
      else
        pos += firstWeekDay - 7;

      if (pos<firstday || (firstday+numdays<=pos))
      { // we are either
        //  painting a day of the previous month or
        //  painting a day of the following month

        if (pos<firstday)
        { // previous month
          drawDate = drawDate.addMonths(-1);
          text.setNum(numDaysPrevMonth+pos-firstday+1);
          drawDate.setYMD(drawDate.year(), drawDate.month(), text.toInt());
        } else { // following month
          drawDate = drawDate.addMonths(1);
          text.setNum(pos-firstday-numdays+1);
          drawDate.setYMD(drawDate.year(), drawDate.month(), text.toInt());
        }
      } else { // paint a day of the current month
        text.setNum(pos-firstday+1);
        drawDate.setYMD(drawDate.year(), drawDate.month(), text.toInt());
      }
    }
    else if (m_type == WEEKLY)
    {
      // TODO: Handle other start weekdays than Monday
      text = TQDate::shortDayName(row);
      text += " ";

      int dayOfWeek = date.dayOfWeek();
      int diff;

      if (row < dayOfWeek)
      {
        diff = -(dayOfWeek - row);
      }
      else
      {
        diff = row - dayOfWeek;
      }

      drawDate = date.addDays(diff);
    }
    else if (m_type == QUARTERLY)
    {
    }

    m_drawDateOrig = drawDate;
    MyMoneyFile *file = MyMoneyFile::instance();
    TQValueList<MyMoneySchedule> schedules;

    try
    {
      int types=0;

      if (!m_filterBills)
      {
        types |= MyMoneySchedule::TYPE_BILL;
      }

      if (!m_filterDeposits)
      {
        types |= MyMoneySchedule::TYPE_DEPOSIT;
      }

      if (!m_filterTransfers)
      {
        types |= MyMoneySchedule::TYPE_TRANSFER;
      }


      schedules = file->scheduleListEx( types,
                                        MyMoneySchedule::OCCUR_ANY,
                                        MyMoneySchedule::STYPE_ANY,
                                        drawDate,
                                        m_filterAccounts);
    }
    catch ( MyMoneyException* e)
    {
      // SAfe to ignore here, cause no schedules might exist
      // for the selected account
      delete e;
    }

    if (schedules.count() >= 1)
    {
      briefWidget.setSchedules(schedules, drawDate);

      int h = briefWidget.height();
      int w = briefWidget.width();

      // Take off five pixels so the mouse cursor
      // will be over the widget
      TQPoint p = TQCursor::pos();
      if (p.y() + h > TQApplication::desktop()->height())
      {
        p.setY(p.y() - (h-5));
      }
      else
        p.setY(p.y() - 5);

      if (p.x() + w > TQApplication::desktop()->width())
      {
        p.setX(p.x() - (w-5));
      }
      else
        p.setX(p.x() - 5);

      briefWidget.move(p);
      briefWidget.show();
    }
    else
    {
      briefWidget.hide();
    }
  }
}

void kMyMoneyScheduledDateTbl::filterBills(bool enable)
{
  m_filterBills = enable;
  repaintContents(false);
}

void kMyMoneyScheduledDateTbl::filterDeposits(bool enable)
{
  m_filterDeposits = enable;
  repaintContents(false);
}

void kMyMoneyScheduledDateTbl::filterTransfers(bool enable)
{
  m_filterTransfers = enable;
  repaintContents(false);
}

#include "kmymoneyscheduleddatetbl.moc"
