/***************************************************************************
 *   Copyright (C) 2008 by SK Communications.                              *
 *   http://kldp.net/projects/nateon/                                      *
 *                                                                         *
 *   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 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   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 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 "listviews.h"

#include <qlabel.h>
#include <qpainter.h>
#include <qpalette.h>
#include <qobjectlist.h>
#include <qpopupmenu.h>
#include <qheader.h>
#include <qregexp.h>

// -----------------------------------------------------------------

MessageHeader::MessageHeader( const MessageHeader &mh )
{
  mid = mh.mid;
  msender = mh.msender;
  mreceivers = mh.mreceivers;
  msubject = mh.msubject;
  mdatetime = mh.mdatetime;
}

MessageHeader &MessageHeader::operator=( const MessageHeader &mh )
{
  mid = mh.mid;
  msender = mh.msender;
  mreceivers = mh.mreceivers;
  msubject = mh.msubject;
  mdatetime = mh.mdatetime;

  return *this;
}

// -----------------------------------------------------------------

Folder::Folder( Folder *parent, const QString &name )
    : QObject( parent, name ), fName( name )
{
	lstMessages.clear();
	lstMessages.setAutoDelete( FALSE );
}

// -----------------------------------------------------------------

FolderListItem::FolderListItem( QListView *parent, Folder *f )
    : QListViewItem( parent )
{
    myFolder = f;
    setText( 0, f->folderName() );

    if ( myFolder->children() )
		insertSubFolders( myFolder->children() );
}

FolderListItem::FolderListItem( FolderListItem *parent, Folder *f )
    : QListViewItem( parent )
{
    myFolder = f;

    setText( 0, f->folderName() );

    if ( myFolder->children() )
		insertSubFolders( myFolder->children() );
}

void FolderListItem::insertSubFolders( const QObjectList *lst )
{
#if 1
    Folder *f;
    for ( f = ( Folder* )( ( QObjectList* )lst )->first(); f; f = ( Folder* )( ( QObjectList* )lst )->next() )
		  (void)new FolderListItem( this, f );
#endif
}

// -----------------------------------------------------------------

MessageListItem::MessageListItem( QListView *parent, Message *m )
    : QListViewItem( parent )
{
    myMessage = m;
    setText( 0, myMessage->header().id() );
    setText( 1, myMessage->header().sender() );
    // setText( 2, myMessage->header().receivers() );
    setText( 2, myMessage->header().subject() );
    setText( 3, myMessage->header().datetime() );
    parent->hideColumn(0);
}

void MessageListItem::paintCell( QPainter *p, const QColorGroup &cg,
								 int column, int width, int alignment )
{
    QColorGroup _cg( cg );
    QColor c = _cg.text();

    if ( myMessage->state() == Message::Unread )
		_cg.setColor( QColorGroup::Text, Qt::red );

    QListViewItem::paintCell( p, _cg, column, width, alignment );

    _cg.setColor( QColorGroup::Text, c );
}

// -----------------------------------------------------------------

ListViews::ListViews( QWidget *parent, const char *name )
    : QSplitter( Qt::Horizontal, parent, name ),
messages(0),
folders(0),
fMemoInbox(0),
fMemoOutbox(0),
fChatBox(0)
{
	lstFolders.clear();
	lstFolders.setAutoDelete( FALSE );

    folders = new QListView( this );

    folders->clear();
    folders->removeColumn(0);
    folders->setRootIsDecorated(false);
    folders->header()->setClickEnabled( FALSE );
    folders->addColumn( "Folder1" );
    folders->header()->hide();
    /*
    initFolders();
    setupFolders();
    */

    // folders->setRootIsDecorated( TRUE );
    setResizeMode( folders, QSplitter::KeepSize );

    QSplitter *vsplitter = new QSplitter( Qt::Vertical, this );

    messages = new QListView( vsplitter );
    messages->addColumn( "" );
    messages->addColumn( i18n("보낸사람") );
    messages->addColumn( i18n("제목") );
    messages->addColumn( i18n("받은날짜") );
    // messages->setColumnAlignment( 1, Qt::AlignRight );
    messages->setAllColumnsShowFocus( TRUE );
    messages->setShowSortIndicator( TRUE );
    messages->setSorting ( 3, false );
    messages->header()->setResizeEnabled(FALSE, 0);
    messages->hideColumn ( 0 );
	messages->setHScrollBarMode( QScrollView::AlwaysOff );
	messages->setSelectionMode( QListView::Extended );
    connect(messages, SIGNAL( contextMenuRequested( QListViewItem *, const QPoint& , int ) ), this, SLOT( slotRMB( QListViewItem *, const QPoint &, int ) ) );
  // connect(messages, SIGNAL( doubleClicked( QListViewItem *, const QPoint& , int ) ), SLOT( slotDoubleClick( QListViewItem *, const QPoint &, int ) ) );

  vsplitter->setResizeMode( messages, QSplitter::KeepSize );

    message = new QTextEdit( vsplitter );
    message->setAlignment( Qt::AlignTop );
    message->setBackgroundMode( PaletteBase );

    connect( folders, SIGNAL( selectionChanged( QListViewItem* ) ), this, SLOT( slotFolderChanged( QListViewItem* ) ) );
    connect( messages, SIGNAL( selectionChanged() ), this, SLOT( slotMessageChanged() ) );
    connect( messages, SIGNAL( currentChanged( QListViewItem * ) ), this, SLOT( slotMessageChanged() ) );

    // messages->setSelectionMode( QListView::Extended );
    QValueList<int> lst;
    lst.append( 170 );
    setSizes( lst );

    dirs = KGlobal::dirs();
	sPicsPath = dirs->findResource( "data", QString( KGlobal::instance()->aboutData()->appName() ) + "/pics/" );
    // createMemoTree();

    setMinimumSize( QSize( 0, 400 ) );
    setMaximumSize( QSize( 32767, 32767 ) );
}

void ListViews::initFolders()
{
#if 1
    // some preparations
    folders->firstChild()->setOpen( TRUE );
    // folders->firstChild()->firstChild()->setOpen( TRUE );
    // folders->setCurrentItem( folders->firstChild()->firstChild()->firstChild() );
    // folders->setSelected( folders->firstChild()->firstChild()->firstChild(), TRUE );
    folders->setSelected( folders->firstChild()->firstChild(), TRUE );
    messages->setSelected( messages->firstChild(), TRUE );
    messages->setCurrentItem( messages->firstChild() );
    messages->hideColumn( 0 );
    // messages->setColumnWidth ( 0, 0 );
    // messages->hideColumn( 1 );
    message->setMargin( 5 );
    int nTotal = messages->width();

    messages->setColumnWidth ( 1, nTotal/4 );
    messages->setColumnWidth ( 2, nTotal/2 );
    messages->setColumnWidth ( 3, nTotal/4 );

    // messages->setResizeMode( QListView::LastColumn);

#endif

#if 0
    unsigned int mcount = 1;
    for ( unsigned int i = 1; i < 20; i++ ) {
		QString str;
		str = QString( "Folder %1" ).arg( i );
		Folder *f = new Folder( 0, str );
		for ( unsigned int j = 1; j < 5; j++ ) {
			QString str2;
			str2 = QString( "Sub Folder %1" ).arg( j );
			Folder *f2 = new Folder( f, str2 );
			for ( unsigned int k = 1; k < 3; k++ ) {
				QString str3;
				str3 = QString( "Sub Sub Folder %1" ).arg( k );
				Folder *f3 = new Folder( f2, str3 );
				initFolder( f3, mcount );
			}
		}
		lstFolders.append( f );
    }
#endif
}

void ListViews::initFolder( Folder *folder, unsigned int &count )
{
/*
    for ( unsigned int i = 0; i < 15; i++, count++ ) {
		QString str;
		str = QString( "Message %1  " ).arg( count );
		QDateTime dt = QDateTime::currentDateTime();
		dt = dt.addSecs( 60 * count );
		MessageHeader mh( "Trolltech <info@trolltech.com>  ", str, dt );

		QString body;
		body = QString( "This is the message number %1 of this application, \n"
						"which shows how to use QListViews, QListViewItems, \n"
						"QSplitters and so on. The code should show how easy\n"
						"this can be done in Qt." ).arg( count );
		Message *msg = new Message( mh, body );
		folder->addMessage( msg );
    }
*/
	Q_UNUSED( folder );
	Q_UNUSED( count );
}

void ListViews::setupFolders()
{
    folders->clear();

    for ( Folder* f = lstFolders.first(); f; f = lstFolders.next() )
		  (void)new FolderListItem( folders, f );
}

void ListViews::slotRMB( QListViewItem* Item, const QPoint & point, int )
{
  QListViewItem* f = folders->currentItem();
  
  if ( f == fMemoOutboxItem )
    menu->setItemEnabled ( 1, FALSE );
  else
    menu->setItemEnabled ( 1, TRUE );
  
  if( Item )
  {
		switch ( getSelectedItemCount() )
	  {
	  case 0:
		  KMessageBox::information( this, i18n("우선 선택을 하세요."), i18n("선택 메뉴") );
		  break;
	  case 1:
		  menu->setItemEnabled ( m_nOpenMenuID, TRUE );
		  menu->setItemEnabled ( m_nSaveMenuID, TRUE );
		  menu->setItemEnabled ( m_nReplyMenuID, TRUE );
		  menu->setItemEnabled ( m_nReplyAllMenuID, TRUE );
		  menu->setItemEnabled ( m_nForwardMenuID, TRUE );
		  menu->setItemEnabled ( m_nChatSaveMenuID, TRUE );
		  menu->popup( point );
		  break;
	  default:
		  menu->setItemEnabled ( m_nOpenMenuID, FALSE );
		  menu->setItemEnabled ( m_nSaveMenuID, FALSE );
		  menu->setItemEnabled ( m_nReplyMenuID, FALSE );
		  menu->setItemEnabled ( m_nReplyAllMenuID, FALSE );
		  menu->setItemEnabled ( m_nForwardMenuID, FALSE );
		  menu->setItemEnabled ( m_nChatSaveMenuID, FALSE );
		  menu->popup( point );
		  break;
	  }
	  // kdDebug() << "Is " << messages->isMultiSelection () << endl;
  }
}


void ListViews::slotFolderChanged( QListViewItem *i )
{
  if ( !i )
	return;
  messages->clear();
  message->setText( "" );

  FolderListItem *item = ( FolderListItem* )i;

  if ( item == fMemoInboxItem )
  {
    emit showMemoInbox();
#ifdef NETDEBUG
    kdDebug() << "1. [ M E M O I N B O X ]" << endl;
#endif
  }
  else if ( item == fMemoOutboxItem )
  {
    emit showMemoOutbox();
#ifdef NETDEBUG
    kdDebug() << "1. [ M E M O O U T B O X ]" << endl;
#endif
  }
  else if ( item == fChatBoxItem )
  {
    emit showChatBox();
#ifdef NETDEBUG
    kdDebug() << "1. [ C H A T B O X ]" << endl;
#endif
  }

  for ( Message* msg = item->folder()->firstMessage(); msg; msg = item->folder()->nextMessage() )
  {
    (void)new MessageListItem( messages, msg );
    messages->hideColumn ( 0 );
  }

  int nTotal = messages->width();
  messages->setColumnWidth ( 1, nTotal/4 );
  messages->setColumnWidth ( 2, nTotal/2 );
  messages->setColumnWidth ( 3, nTotal/4 );

  messages->setSelected( messages->firstChild(), TRUE );
  messages->setCurrentItem( messages->firstChild() );
}

void ListViews::slotMessageChanged()
{
	switch ( getSelectedItemCount() )
	{
	case 0:
		emit multiItemsSelected( FALSE );
		break;
	case 1:
		emit multiItemsSelected( FALSE );
		break;
	default:
		emit multiItemsSelected( TRUE );
		break;
	}
	
    QListViewItem *i = messages->currentItem();
    if ( !i )
		return;

    if ( !i->isSelected() ) {
		message->setText( "" );
		return;
    }

    MessageListItem *item = ( MessageListItem* )i;

    Message *msg = item->message();

    if ( msg->header().receivers().length() > 1 )
    {
      QString text;
      QString tmp = msg->body();

      tmp = tmp.replace( '\n', "<br>" );
      // tmp = tmp.replace( ">", "&gt;" );

      QString sSender( msg->header().sender() );
      sSender.replace( "<", "&lt;" );
      sSender.replace( ">", "&gt;" );

      QString sReceivers( msg->header().receivers() );
	    sReceivers.replace(QRegExp("<\b[^>]*>"), "");
	    /*
      sReceivers.replace( "<", "&lt;" );
      sReceivers.replace( ">", "&gt;" );
	    */

      text = QString(
                      "<big><b>%0</b></big><br>"
                      "%1 : "
                      "%2<br>"
                      "%3 : "
                      "%4<br>"
                      "%5 : "
                      "%6<br>"
                      "<hr>%7" ).
		    arg( msg->header().subject() ).
		    arg( QString::fromUtf8( "보낸 사람" ) ).
		    arg( sSender ).
		    arg( QString::fromUtf8( "받는 사람" ) ).
		    arg( sReceivers ).
		    arg( QString::fromUtf8( "작성일" ) ).
		    arg( msg->header().datetime() ).
		    arg( tmp );

      message->setText( text );
      message->setWordWrap( QTextEdit::WidgetWidth );
      message->setReadOnly(TRUE);
      msg->setState( Message::Read );
    }
    else
    {
      QString text;
      QString tmp = msg->body();

      tmp = tmp.replace( '\n', "<br>" );
      // tmp = tmp.replace( ">", "&gt;" );

      QString sSender( msg->header().sender() );
      sSender.replace( "<", "&lt;" );
      sSender.replace( ">", "&gt;" );

      QString sReceivers( msg->header().receivers() );
	    sReceivers.replace(QRegExp("<\b[^>]*>"), "");
	    /*
      sReceivers.replace( "<", "&lt;" );
      sReceivers.replace( ">", "&gt;" );
	     */

      text = QString(
                      "<big><b>%0</b></big><br>"
                      "%1 : %2<br>"
                      "%3 : %4<br><hr>%5" ).
		    arg( msg->header().subject() ).
		    arg( QString::fromUtf8( "대화 상대" ) ).
		    arg( sSender ).
		    arg( QString::fromUtf8( "날 짜" ) ).
		    arg( msg->header().datetime() ).
		    arg( tmp );

      message->setText( text );
      message->setWordWrap( QTextEdit::WidgetWidth );
      message->setReadOnly(TRUE);
      msg->setState( Message::Read );
    }
  emit setREAD( i );
}

void ListViews::createMemoTree()
{
  Folder *f00 = new Folder( 0, i18n("쪽지함[PC]"));
  FolderListItem *fItem00 = new FolderListItem( folders, f00 );
  fItem00->setPixmap( 0, QPixmap( sPicsPath + "tmh_list_mess_box.png" ) );
  fItem00->setOpen(true);

  fMemoInbox = new Folder( 0, i18n("받은쪽지함"));
  fMemoInboxItem = new FolderListItem( fItem00, fMemoInbox );
  fMemoInboxItem->setPixmap( 0, QPixmap( sPicsPath + "tmh_list_mess_receivbox.png" ) );

  fMemoOutbox = new Folder( 0, i18n("보낸쪽지함"));
  fMemoOutboxItem = new FolderListItem( fItem00, fMemoOutbox );
  fMemoOutboxItem->setPixmap( 0, QPixmap( sPicsPath + "tmh_list_mess_sentbox.png" ) );
/*
  Folder *f03 = new Folder( 0, i18n("개인쪽지함"));
  FolderListItem *fItem03 = new FolderListItem( fItem00, f03 );
  fItem03->setPixmap( 0, QPixmap( sPicsPath + "tmh_list_mess_indivbox.png" ) );
*/
}

void ListViews::createChatTree()
{
  Folder *f00 = new Folder( 0, i18n("대화함[PC]"));
  FolderListItem *fItem00 = new FolderListItem( folders, f00 );
  fItem00->setPixmap( 0, QPixmap( sPicsPath + "tmh_d_list_conv_box.png" ) );
  fItem00->setOpen(true);

  fChatBox = new Folder( 0, i18n("개인대화함"));
  fChatBoxItem = new FolderListItem( fItem00, fChatBox );
  fChatBoxItem->setPixmap( 0, QPixmap( sPicsPath + "tmh_d_list_indiv_box.png" ) );
}

void ListViews::addMemoInbox(const QString & sID, const QString & sSender, const QString & sReceivers, const QString & sSubject, const QString & sBody, const QString & sDateTime, bool bReaded)
{
  MessageHeader mh( sID, sSender, sReceivers, sSubject, sDateTime );
  Message *msg = new Message( mh, sBody );
  if ( bReaded )
    msg->setState( Message::Read );
  fMemoInbox->addMessage( msg );
}

void ListViews::slotUNREAD()
{
  QListViewItem *i = messages->currentItem();
  if ( !i )
    return;

  if ( !i->isSelected() ) {
    message->setText( "" );
    return;
  }

  MessageListItem *item = ( MessageListItem* )i;

  Message *msg = item->message();
  msg->setState( Message::Unread );

  emit setUNREAD( i );
}

void ListViews::slotReply()
{
}

void ListViews::slotReplyAll()
{
}

void ListViews::slotForward()
{
}

void ListViews::slotDelete()
{
}

void ListViews::resizeEvent(QResizeEvent * e)
{
  QSplitter::resizeEvent(e);

  int nTotal = messages->width();
  messages->hideColumn(0);
  messages->setColumnWidth ( 1, nTotal/4 );
  messages->setColumnWidth ( 2, nTotal/2 );
  messages->setColumnWidth ( 3, nTotal/4 );
}

void ListViews::showEvent ( QShowEvent * e )
{
  QSplitter::showEvent(e);

  int nTotal = messages->width();
  messages->hideColumn(0);
  messages->setColumnWidth ( 1, nTotal/4 );
  messages->setColumnWidth ( 2, nTotal/2 );
  messages->setColumnWidth ( 3, nTotal/4 );
}

void ListViews::addMemoOutbox(const QString & sID, const QString & sSender, const QString & sReceivers, const QString & sSubject, const QString & sBody, const QString & sDateTime, bool bReaded)
{
  MessageHeader mh( sID, sSender, sReceivers, sSubject, sDateTime );
  Message *msg = new Message( mh, sBody );
  if ( bReaded )
    msg->setState( Message::Read );
  fMemoOutbox->addMessage( msg );
}

void ListViews::addChatBox(const QString & sID, const QString & sSender, const QString & sReceivers, const QString & sSubject, const QString & sBody, const QString & sDateTime, bool bReaded)
{
  MessageHeader mh( sID, sSender, sReceivers, sSubject, sDateTime );
  Message *msg = new Message( mh, sBody );
  if ( bReaded )
    msg->setState( Message::Read );
  fChatBox->addMessage( msg );
}

int ListViews::getFolderIndex()
{
  QListViewItem* item = folders->currentItem();
  if ( item == fMemoInboxItem )
  {
    return 0;
#ifdef NETDEBUG
    kdDebug() << "getFolderIndex [ M E M O I N B O X ]" << endl;
#endif
  }
  else if ( item == fMemoOutboxItem )
  {
    return 1;
#ifdef NETDEBUG
    kdDebug() << "getFolderIndex [ M E M O O U T B O X ]" << endl;
#endif
  }
  else if ( item == fChatBoxItem )
  {
    return 0;
#ifdef NETDEBUG
    kdDebug() << "getFolderIndex [ C H A T B O X ]" << endl;
#endif
  }
	return 0;
}

void ListViews::clearList()
{
  // messages->clear();
  // QListViewItem* item = folders->currentItem();
  FolderListItem *item = ( FolderListItem* )(folders->currentItem());
  
  if ( item == fMemoInboxItem )
  {
    fMemoInbox->clear();
#ifdef NETDEBUG
    kdDebug() << "2. [ M E M O I N B O X ]" << endl;
#endif
  }
  else if ( item == fMemoOutboxItem )
  {
    fMemoOutbox->clear();
#ifdef NETDEBUG
    kdDebug() << "2. [ M E M O O U T B O X ]" << endl;
#endif
  }
  else if ( item == fChatBoxItem )
  {
    fChatBox->clear();
#ifdef NETDEBUG
    kdDebug() << "2. [ C H A T B O X ]" << endl;
#endif
  }

}

void ListViews::refresh()
{
  FolderListItem *item = ( FolderListItem* )(folders->currentItem());
  // FolderListItem *item = ( FolderListItem* )i;
  messages->clear();
  message->setText( "" );

  for ( Message* msg = item->folder()->firstMessage(); msg; msg = item->folder()->nextMessage() )
  {
    (void)new MessageListItem( messages, msg );
    messages->hideColumn ( 0 );
  }

  int nTotal = messages->width();
  messages->setColumnWidth ( 1, nTotal/4 );
  messages->setColumnWidth ( 2, nTotal/2 );
  messages->setColumnWidth ( 3, nTotal/4 );

  messages->setSelected( messages->firstChild(), TRUE );
  messages->setCurrentItem( messages->firstChild() );
}

QListViewItem* ListViews::getCurrentItem()
{
  return messages->currentItem();
}

void ListViews::removeCurrentItem()
{
  messages->removeItem( messages->currentItem() );
  return;
}

void ListViews::createMemoMouseMenu()
{
  menu = new QPopupMenu( messages );
  menu->insertItem( i18n( "읽지않은 상태로 변경(&B)" ), this, SLOT( slotUNREAD() ), 0, 0 );
  menu->insertSeparator();
	m_nOpenMenuID = menu->insertItem( i18n( "열기(&O)" ), this, SLOT( slotOpen() ), Key_Enter, 1 );
	m_nSaveMenuID = menu->insertItem( i18n( "저장(&S)" ), this, SLOT( slotSave() ), CTRL+Key_S, 2 );
  menu->insertSeparator();
	m_nReplyMenuID = menu->insertItem( i18n( "답장(&R)" ), this, SLOT( slotReply() ), CTRL+Key_R, 3 );
	m_nReplyAllMenuID = menu->insertItem( i18n( "전체 답장(&A)" ), this, SLOT(slotReplyAll()), CTRL+SHIFT+Key_R, 4 );
	m_nForwardMenuID = menu->insertItem( i18n( "전달(&F)" ), this, SLOT(slotForward()), CTRL+SHIFT+Key_F, 5 );
  menu->insertSeparator();
	m_nDeleteMenuID = menu->insertItem( i18n( "삭제(&D)" ), this, SLOT(slotDelete()), Key_Delete, 6 );
}

void ListViews::createChatMouseMenu()
{
  menu = new QPopupMenu( messages );
	m_nChatSaveMenuID = menu->insertItem( i18n( "저장(&S)" ), this, SLOT( slotChatSave() ), CTRL+Key_S, 0 );
  menu->insertSeparator();
	m_nChatDeleteMenuID = menu->insertItem( i18n( "삭제(&D)" ), this, SLOT(slotChatDelete()), Key_Delete, 1 );
}

void ListViews::slotSave()
{
}

void ListViews::slotChatSave()
{
}

void ListViews::slotChatDelete()
{
}

void ListViews::slotOpen()
{
  // emit showMemo( messages->currentItem()->text(0) );
}

int ListViews::getSelectedItemCount()
{
	QListViewItem * myChild = messages->firstChild();
	int nCount = 0;
	while( myChild ) {
		if ( messages->isSelected( myChild ) )
			nCount++;
		myChild = myChild->nextSibling();
	}
	return nCount;
}

void ListViews::removeItem(QListViewItem * item)
{
	messages->removeItem( item );
	return;
}


#if 0
void ListViews::slotDoubleClick(QListViewItem * pItem, const QPoint &, int nPoint)
{
  kdDebug() << "UUID :[" << pItem->text(0) << "]" << endl;
  emit doubleClicked( pItem->text(0) );
}
#endif

#include "listviews.moc"

