/***************************************************************************
                          kateviewspace.cpp  -  description
                             -------------------
    begin                : Mon Jan 15 2001
    copyright            : (C) 2001, 2002 by Anders Lund
    email                : anders@alweb.dk
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "kateviewspace.h"
#include "kateviewspace.moc"

#include "katemainwindow.h"

#include <kiconloader.h>
#include <klocale.h>
#include <qwidgetstack.h>
#include <ksimpleconfig.h>
#include <qpainter.h>
#include <qlabel.h>
#include <qcursor.h>

//BEGIN KVSSBSep
/*
   "KateViewSpaceStatusBarSeparator"
   A 2 px line to separate the statusbar from the view.
   It is here to compensate for the lack of a frame in the view,
   I think Kate looks very nice this way, as QScrollView with frame
   looks slightly clumsy...
   Slight 3D effect. I looked for suitable QStyle props or methods,
   but found none, though maybe it should use QStyle::PM_DefaultFrameWidth
   for height (TRY!).
   It does look a bit funny with flat styles (Light, .Net) as is,
   but there are on methods to paint panel lines separately. And,
   those styles tends to look funny on their own, as a light line
   in a 3D frame next to a light contents widget is not functional.
   Also, QStatusBar is up to now completely ignorant to style.
   -anders
*/
class KVSSBSep : public QWidget {
public:
  KVSSBSep( KateViewSpace *parent=0) : QWidget(parent)
  {
    setFixedHeight( 2 );
  }
protected:
  void paintEvent( QPaintEvent *e )
  {
    QPainter p( this );
    p.setPen( colorGroup().shadow() );
    p.drawLine( e->rect().topLeft(), e->rect().topRight() );
    p.setPen( ((KateViewSpace*)parentWidget())->isActiveSpace() ? colorGroup().light() : colorGroup().midlight() );
    p.drawLine( e->rect().bottomLeft(), e->rect().bottomRight() );
  }
};
//END KVSSBSep

//BEGIN KateViewSpace

KateViewSpace::KateViewSpace(QWidget* parent, const char* name)
  : QVBox(parent, name)
{
   mViewList.setAutoDelete(false);

  stack = new QWidgetStack( this );
  setStretchFactor(stack, 1);
  stack->installEventFilter( this );
  stack->setFocus();
  sep = new KVSSBSep( this );
  mStatusBar = new KateVSStatusBar(this);
  mIsActiveSpace = false;
  mViewCount = 0;
}

KateViewSpace::~KateViewSpace()
{
}

void KateViewSpace::polish()
{
  mStatusBar->show();
}

void KateViewSpace::addView(Kate::View* v, bool show)
{
  uint id = mViewList.count();
  stack->addWidget(v, id);
  if (show) {
    mViewList.append(v);
    showView( v );
  }
  else {
    Kate::View* c = mViewList.current();
    mViewList.prepend( v );
    showView( c );
  }
}

void KateViewSpace::removeView(Kate::View* v)
{
//  mStatusBar->slotClear ();
  mViewList.remove (v);
  stack->removeWidget (v);
// FIXME only if active - focus stack->visibleWidget() or back out
  if (currentView() != 0L)
    stack->raiseWidget(mViewList.current());
  else if (mViewList.count() > 0)
    stack->raiseWidget(mViewList.last());
}

bool KateViewSpace::showView(Kate::View* v)
{
  Kate::Document* d = v->getDoc();
  QPtrListIterator<Kate::View> it (mViewList);

  it.toLast();
  for( ; it.current(); --it ) {
    if (it.current()->getDoc() == d) {
      Kate::View* kv = it.current();
      mViewList.removeRef( kv );
      mViewList.append( kv );
//      kv->show();
      stack->raiseWidget( kv );
      return true;
    }
  }
   return false;
}

bool KateViewSpace::showView(uint documentNumber)
{
  QPtrListIterator<Kate::View> it (mViewList);

  it.toLast();
  for( ; it.current(); --it ) {
    if (((Kate::Document*)it.current()->getDoc())->documentNumber() == documentNumber) {
      Kate::View* kv = it.current();
      mViewList.removeRef( kv );
      mViewList.append( kv );
//      kv->show();
      stack->raiseWidget( kv );
      return true;
    }
  }
   return false;
}


Kate::View* KateViewSpace::currentView()
{
  if (mViewList.count() > 0)
    return (Kate::View*)stack->visibleWidget();

  return 0L;
}

bool KateViewSpace::isActiveSpace()
{
  return mIsActiveSpace;
}

void KateViewSpace::setActive( bool b, bool )
{
  mIsActiveSpace = b;

  // change the statusbar palette and make sure it gets updated
  QPalette pal( palette() );
  if ( ! b )
  {
    pal.setColor( QColorGroup::Background, pal.active().mid() );
    pal.setColor( QColorGroup::Light, pal.active().midlight() );
  }
  mStatusBar->setPalette( pal );
  mStatusBar->update();
  sep->update();
  // enable the painting of the icon and repaint it ;-)
  // mStatusBar->showActiveViewIndicator( showled );
}

bool KateViewSpace::event( QEvent *e )
{
  if ( e->type() == QEvent::PaletteChange )
  {
    setActive( mIsActiveSpace );
    return true;
  }
  return QVBox::event( e );
}

void KateViewSpace::slotStatusChanged (Kate::View *view, int r, int c, int ovr, bool block, int mod, QString msg)
{
  if ((QWidgetStack *)view->parentWidget() != stack)
    return;
  mStatusBar->setStatus( r, c, ovr, block, mod, msg );
}

void KateViewSpace::saveFileList( KSimpleConfig* config, int myIndex )
{
  QString group = QString("viewspace%1").arg( myIndex );

  // Save file list, includeing cursor position in this instance.
  QPtrListIterator<Kate::View> it(mViewList);

  int idx = 0;
  for (; it.current(); ++it) {
    if ( !it.current()->getDoc()->url().isEmpty() )
    {
      // filenames, group: "splitter<n>"
      config->setGroup( group );
      config->writeEntry( QString("file%1").arg( idx ), it.current()->getDoc()->url().prettyURL() );
      // view config, group: "splitter<n>:file<m>"
      QString vgroup = QString("%1:file%2").arg(group).arg( idx );
      config->setGroup( vgroup );
      it.current()->writeSessionConfig( config );
      // put the view group in group "<filename>",
      // if user don't want viewconfig restored the config of the last view for doc will be used
      config->setGroup( it.current()->getDoc()->url().prettyURL() );
      config->writeEntry( "viewconfig", vgroup );
    }
    idx++;
  }
}


//END KateViewSpace

//BEGIN KateVSStatusBar
///////////////////////////////////////////////////////////
// KateVSStatusBar implementation
///////////////////////////////////////////////////////////

KateVSStatusBar::KateVSStatusBar ( KateViewSpace *parent, const char *name )
  : KStatusBar( parent, name )
{
   m_lineColLabel = new QLabel( i18n(" Line: 1 Col: 0 "), this );
   addWidget( m_lineColLabel, 0, false );
   m_lineColLabel->setAlignment( Qt::AlignCenter );
   m_lineColLabel->installEventFilter( this );

   m_modifiedLabel = new QLabel( QString("   "), this );
   addWidget( m_modifiedLabel, 0, false );
   m_modifiedLabel->setAlignment( Qt::AlignCenter );
   m_modifiedLabel->installEventFilter( this );

   m_insertModeLabel = new QLabel( i18n(" INS "), this );
   addWidget( m_insertModeLabel, 0, false );
   m_insertModeLabel->setAlignment( Qt::AlignCenter );
   m_insertModeLabel->installEventFilter( this );

   m_selectModeLabel = new QLabel( i18n(" NORM "), this );
   addWidget( m_selectModeLabel, 0, false );
   m_selectModeLabel->setAlignment( Qt::AlignCenter );
   m_selectModeLabel->installEventFilter( this );

   m_fileNameLabel=new QLabel("",this);
   addWidget( m_fileNameLabel,/*0,true*/1, true );
   m_selectModeLabel->setAlignment( /*Qt::AlignRight*/Qt::AlignLeft );
   m_selectModeLabel->installEventFilter( this );

   installEventFilter( this );
}

KateVSStatusBar::~KateVSStatusBar ()
{
}

void KateVSStatusBar::setStatus( int r, int c, int ovr, bool block, int mod, QString msg )
{
  m_lineColLabel->setText(
    i18n(" Line: %1 Col: %2 ").arg(KGlobal::locale()->formatNumber(r+1, 0))
                              .arg(KGlobal::locale()->formatNumber(c, 0)) );

  if (ovr == 0)
    m_insertModeLabel->setText( i18n(" R/O ") );
  else if (ovr == 1)
    m_insertModeLabel->setText( i18n(" OVR ") );
  else if (ovr == 2)
    m_insertModeLabel->setText( i18n(" INS ") );

  if (mod == 1)
    m_modifiedLabel->setText( QString(" * ") );
  else
    m_modifiedLabel->setText( QString("   ") );

  m_selectModeLabel->setText( block ? i18n(" BLK ") : i18n(" NORM ") );

  m_fileNameLabel->setText( msg );
}

void KateVSStatusBar::showMenu()
{
   KMainWindow* mainWindow = static_cast<KMainWindow*>( topLevelWidget() );
   QPopupMenu* menu = static_cast<QPopupMenu*>( mainWindow->factory()->container("viewspace_popup", mainWindow ) );
   menu->exec(QCursor::pos());
}

bool KateVSStatusBar::eventFilter(QObject*,QEvent *e)
{
   if (e->type()==QEvent::MouseButtonPress)
   {
      if ( ((KateViewSpace*)parentWidget())->currentView() )
        ((KateViewSpace*)parentWidget())->currentView()->setFocus();

      if ( ((QMouseEvent*)e)->button()==RightButton)
         showMenu();

      return true;
   }
   return false;
}

//END KateVSStatusBar
