/****************************************************************************
**
** Copyright (C) 2001-2006 Frank Hemer <frank@hemer.org>,
**                         Tilo Riemer <riemer@crossvc.com>,
**                         Jose Hernandez <joseh@tesco.net>
**
**
**----------------------------------------------------------------------------
**
**----------------------------------------------------------------------------
**
** CrossVC is available under two different licenses:
**
** If CrossVC is linked against the GPLed version of Qt 
** CrossVC is released under the terms of GPL also.
**
** If CrossVC is linked against a nonGPLed version of Qt 
** CrossVC is released under the terms of the 
** CrossVC License for non-Unix platforms (CLNU)
**
**
** CrossVC License for non-Unix platforms (CLNU):
**
** Redistribution and use in binary form, without modification, 
** are permitted provided that the following conditions are met:
**
** 1. Redistributions in binary form must reproduce the above copyright
**    notice, this list of conditions and the following disclaimer in the
**    documentation and/or other materials provided with the distribution.
** 2. It is not permitted to distribute the binary package under a name
**    different than CrossVC.
** 3. The name of the authors may not be used to endorse or promote
**    products derived from this software without specific prior written
**    permission.
** 4. The source code is the creative property of the authors.
**    Extensions and development under the terms of the Gnu Public License
**    are limited to the Unix platform. Any distribution or compilation of 
**    the source code against libraries licensed other than gpl requires 
**    the written permission of the authors.
**
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR 
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
**
**
** CrossVC License for Unix platforms:
**
** 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, version 2 of the License.
** This program 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 General Public License version 2 for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software Foundation,
** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
*****************************************************************************/

#include "config.h"

#include <ctype.h>
#include <qpainter.h>
#include <qregexp.h>
#include <qscrollbar.h>
#include "CvsFileViewer.h"


class CvsFileViewerItem {
 public:
   QString text [CvsFileViewer_NUMCOLS];
   QColor color;
};


class CvsFileViewerItemList : public QPtrList<CvsFileViewerItem> {
 protected:
   virtual int compareItems (QCollection::Item item1, QCollection::Item item2) {
      return ((static_cast<CvsFileViewerItem*>(item1)->text[0]
		    == static_cast<CvsFileViewerItem*>(item2)->text[0]) ? 0 : 1);
   }
};


CvsFileViewer::CvsFileViewer (QWidget *parent, const char *name)
   : QtTableView (parent, name)
{
   QFontMetrics fm(font());

   ColumnWidth.fill (0, CvsFileViewer_NUMCOLS);
   ColumnWidth[0] = fm.width("99999");

   setFocusPolicy (QWidget::WheelFocus);
   setNumRows (0);
   setNumCols (CvsFileViewer_NUMCOLS);
   setTableFlags (Tbl_autoVScrollBar |
	 Tbl_autoHScrollBar|
	 Tbl_smoothVScrolling);

   setFrameStyle (QFrame::WinPanel | QFrame::Sunken);
   setBackgroundMode (PaletteBase);
   setWFlags (WResizeNoErase);

   // Use variable cellwidth
   setCellWidth (0);
   setCellHeight (fm.lineSpacing());

   items = new CvsFileViewerItemList;
   items->setAutoDelete(true);
}


CvsFileViewer::~CvsFileViewer () {
 delete items;
}

void CvsFileViewer::wheelEvent( QWheelEvent *e) {
   QtTableView::wheelEvent(e);
   int d = e->delta();
   int v = verticalScrollBar()->value();
   int l = verticalScrollBar()->lineStep();
   l *= 3;//scroll 3 lines per wheel movement seems to be the qt default
   if (d > 0) {
      d = v - l;
   } else {
      d = v + l;
   }
   verticalScrollBar()->setValue(d);
}

void CvsFileViewer::append (QString Text, QString Revision,
      QString Author, QString Date, int lineNum) {
   CvsFileViewerItem *item = new CvsFileViewerItem;
   QFontMetrics fm(font());
   bool bUpdateTblSize = false;
   int LocalColumnWidth;

   if (lineNum == -1) {
      item->text[0].setNum (items->count() + 1);
   } else if (lineNum == 0) {
      item->text[0] = "";
   } else {
      item->text[0].setNum(lineNum);
   }
   // remove trailing whitespace from text line
   item->text[1] = " " + Revision + " ";
   item->text[2] = " " + Author + " ";
   item->text[3] = " " + Date + " ";
   item->text[4] = " " + Text.replace (QRegExp("[ \t]*$"), " ");
   item->color = getColor(Revision,Author,Date);
   items->append(item);

   int i;
   for (i=0; i < (int)CvsFileViewer_NUMCOLS; i++) {
      LocalColumnWidth = fm.width (item->text[i]);
      if (LocalColumnWidth > ColumnWidth[i]) {
	 ColumnWidth[i] = LocalColumnWidth;
	 bUpdateTblSize = true;
      }
   }

   if (bUpdateTblSize)
      updateTableSize();

   setNumRows(numRows()+1);
}


int CvsFileViewer::cellWidth (int col) {
   return (ColumnWidth[col]);
}


QSize CvsFileViewer::sizeHint() const {
   QFontMetrics fm(font());
   return QSize( 4*fm.width("0123456789"), fm.lineSpacing()*8 );
}


void CvsFileViewer::paintCell (QPainter *p, int row, int col) {
   static QColor gray = QColor(128,128,128);
   static QColor white = QColor(255,255,255);
   static QColor black = QColor(0,0,0);

   CvsFileViewerItem *item = items->at(row);if (!item) qDebug("item is null");
   QColor fgColor, bgColor;
    
   switch (col) {
      case 0:
	 bgColor = gray;
	 fgColor = white;
	 break;
      case 1:
      case 2:
      case 3:
	 if (item->text[0].isEmpty()) {
	    bgColor = gray;
	    fgColor = white;
	 } else {
	    bgColor = item->color;
	    fgColor = gray;
	 }
	 break;

      case 4: {
	 if (item->text[0].isEmpty()) {
	    bgColor = gray;
	    fgColor = red;
	    break;
	 } else {
	    bgColor = item->color;
	    fgColor = black;
	    break;
	 }
      }
   }

   int width = cellWidth(col);
   int height = cellHeight();

   p->setPen (fgColor);
   p->fillRect (0, 0, width, height, bgColor);
   p->drawText (0, 0, width, height, AlignLeft, item->text[col]);
}    

QColor CvsFileViewer::getColor(QString & rev, QString & date, QString & author) {
   static QColor col1 = QColor(190,255,190);//light green
   static QColor col2 = QColor(60,225,255);//light blue
   static QString ls_rev = "";
   static QString ls_author = "";
   static QString ls_date = "";
   static QColor lastColor = col1;
   bool changed = false;
   if (rev != ls_rev) {
      ls_rev = rev;
      changed = true;
   }
   if (author != ls_author) {
      ls_author = author;
      changed = true;
   }
   if (date != ls_date) {
      ls_date = date;
      changed = true;
   }
   if (changed) {
      if (lastColor == col1) {
	 lastColor = col2;
      } else {
	 lastColor = col1;
      }
   }
   return lastColor;
}

