/* ====================================================================
 * Copyright (c) 2003-2008  Martin Hauner
 *                          http://subcommander.tigris.org
 *
 * Subcommander is licensed as described in the file doc/COPYING, which
 * you should have received as part of this distribution.
 * ====================================================================
 */

// sc
#include "config.h"
#include "SingleTextWidget.h"
#include "sublib/TextModel.h"
#include "sublib/NullTextModel.h"
#include "util/String.h"

// sc gui
#include "TextWidget.h"
#include "TextLineNrWidget.h"

// qt
#include <QtCore/QVariant>
#include <QtGui/QLayout>
#include <QtGui/QScrollBar>
#include <QtGui/QPushButton>
#include <QtGui/QToolTip>
#include <QtGui/QHBoxLayout>
#include <QtGui/QLineEdit>
#include <QtGui/QCheckBox>

// sys
#include <stdio.h>
#include <algorithm>
#include <assert.h>



static NullTextModel NullText;

SingleTextWidget::SingleTextWidget( QWidget *parent, const char *name )
: super( parent, name )
{
  // base class layout, we only fill the 0,0 position
  QGridLayout* gl = (QGridLayout*)layout();
  {
    QWidget*     iw  = new QWidget(this);
    QGridLayout* iwl = new QGridLayout(iw);
    iwl->setContentsMargins(1,1,1,1);
    iwl->setSpacing(2);
    gl->addWidget( iw, 0, 0 );
    {
      // first row
      _label = new QLineEdit(iw);
      _label->setText( _q("left...") );
      _label->setReadOnly(true);
      _label->setFrame(false);
      QPalette pal = _label->palette();
      pal.setColor( QPalette::Base, Qt::transparent );
      _label->setPalette(pal);
      //_label->setProperty("readOnly", QVariant(true) );
      //_label->setStyleSheet( "background: palette(window)" );
      iwl->addWidget( _label, 0, 0, 1, 1 );
      
      // second
      QFrame* f = new QFrame(iw);
      f->setFrameStyle( QFrame::HLine | QFrame::Sunken );
      f->setLineWidth(1);
      iwl->addWidget( f, 1, 0, 1, 1 );

      // third
      QHBoxLayout* mltb = new QHBoxLayout;
      mltb->setMargin(0);
      mltb->setSpacing(0);
      iwl->addLayout( mltb, 2, 0, 1, 1 );
      {
        _line = new TextLineNrWidget(iw);
        _text = new TextWidget(iw);
        mltb->addWidget(_line);
        mltb->addWidget(_text);
      }
    }
  }
  connect( _text, SIGNAL(xChanged(int)), SLOT(xChange(int)) );
  connect( _text, SIGNAL(yChanged(int)), SLOT(yChange(int)) );
  connect( _text, SIGNAL(sizeChanged()), SLOT(sizeChanged()) );
}

SingleTextWidget::~SingleTextWidget()
{
}

void SingleTextWidget::setModel( TextModel* model )
{
  _text->setModel( model, &NullText );
  _line->setModel( model );
  _label->setText( model->getSourceName().getStr() );
  QToolTip::add( _label, model->getSourceName().getStr() );
}

void SingleTextWidget::setModel( DiffInfoModel* info )
{
  assert(false);
}

void SingleTextWidget::setLabel( const sc::String& l )
{
  if( l.getCharCnt() > 0 )
  {
    _label->setText( (const char*)l );
  }
}

void SingleTextWidget::enableSelection( bool enable )
{
  _text->enableSelection(enable);
}

void SingleTextWidget::setEditable( bool editable )
{
  _text->setEditable(editable);
}

void SingleTextWidget::vsbChange(int y)
{
  _text->setScrollPosY(y);
  _line->setScrollPosY(y);
}

void SingleTextWidget::hsbChange(int x)
{
  _text->setScrollPosX(x);
}

void SingleTextWidget::xChange(int x)
{
  if( _hsb->value() == x )
  {
    return;
  }

  _hsb->setValue(x);
}

void SingleTextWidget::yChange(int y)
{
  if( _vsb->value() == y )
  {
    return;
  }

  _vsb->setValue(y);
}

void SingleTextWidget::sizeChanged()
{
  _line->update();
}

QSize SingleTextWidget::getScrollSizeHint()
{
  return _text->sizeHint();
}

QSize SingleTextWidget::getScrollSizeCurr()
{
  return _text->size();
}

TextWidget* SingleTextWidget::getText() const
{
  return _text;
}

void SingleTextWidget::jumpToLine( int line )
{
  int ypos = _text->calcLineY(line,true);
  vsbChange(ypos);
  
  // scrolling up trashes the horizontal scrollbar on MacOSX
  _hsb->update();

  if( _vsb->value() == ypos )
  {
    return;
  }

  _vsb->setValue(ypos);
}

void SingleTextWidget::jumpToBlock( int block )
{
  BlockInfo bi = _text->getModel()->getBlockInfo( block );

  if( bi.isEmpty() )
  {
    return;
  }

  jumpToLine( bi.getStart() );
}

void SingleTextWidget::update()
{
  _text->update();
  _line->update();
  super::update();
}

void SingleTextWidget::setAcceptDrops(bool on)
{
  _text->setAcceptDrops(true);
}
