/*
 * Kivio - Visual Modelling and Flowcharting
 * Copyright (C) 2000-2001 theKompany.com & Dave Marotti
 *
 * 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.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
#include "stencilbarbutton.h"

#include <kiconloader.h>
#include <kstringhandler.h>
#include <tqapplication.h>
#include <tqstyle.h>
#include <tqpainter.h>
#include <tqpixmap.h>
#include <tqtooltip.h>
#include <kdebug.h>
#include "tqdrawutil.h"

using namespace Kivio;

DragBarButton::DragBarButton( const TQString& text, TQWidget* parent, const char* name )
: TQPushButton(text,parent,name)
{
  m_pIcon = 0L;
  m_bPressed = false;
  m_bDragged = false;
  m_bMouseOn = false;
  m_bClose = false;
  m_orientation = TQt::Vertical;

  const char* stencil_xpm[] = {
  "12 12 17 1",
  ".	c #08009A",
  "+	c #9A9C10",
  "@	c None",
  "#	c #0800A1",
  "$	c #FAFD00",
  "%	c #080092",
  "&	c #F9FC07",
  "*	c #F9FC00",
  "=	c #070094",
  "-	c #F4F70C",
  ";	c #F6F900",
  ">	c #08008D",
  ",	c #F7FA00",
  "'	c #C00101",
  ")	c #C20904",
  "!	c #C90000",
  "~	c #BC0000",
  ".......+++@@",
  "..#...$$$$+@",
  "..%..&$***$+",
  ".=..-***$;*+",
  ".>.$**$*$,*+",
  "..;**$$$$,*+",
  ".$')!!!!!!!~",
  "..-!!!!!!!!+",
  "...-!!!!!!!+",
  "....-!!!!!++",
  "....%-!!+++@",
  "......++++@@"};

  setPixmap(stencil_xpm);

  const TQColorGroup& g = colorGroup();
  TQColor c = g.buttonText();

  int cr, cg, cb;
  TQString line;
  c.rgb( &cr, &cg, &cb );
  line.sprintf(". c #%02X%02X%02X",cr,cg,cb);

  const char* close_xpm[] = {
  "8 7 2 1",
  "x c None",
  (const char*)line.ascii(),
  "xxxxxxxx",
  "x..xx..x",
  "xx....xx",
  "xxx..xxx",
  "xx....xx",
  "x..xx..x",
  "xxxxxxxx"
  };
  m_pClosePix = new TQPixmap(close_xpm);

  TQToolTip::add(this, text);
}

DragBarButton::~DragBarButton()
{
  delete m_pClosePix;
  delete m_pIcon;

  kdDebug(43000) << "DragBarButton - AHHHHHH I'M DYING!" << endl;
}

void DragBarButton::drawButton( TQPainter* paint )
{
  TQSize pixSize;

  if(m_orientation == TQt::Vertical) {
    pixSize = TQSize(width(), height());
  } else {
    pixSize = TQSize(height(), width());
  }

  TQPixmap pix(pixSize.width(), pixSize.height());
  pix.fill(eraseColor());
  TQPainter pixPainter(&pix);

  const TQColorGroup& g = colorGroup();
  style().drawControl( TQStyle::CE_PushButton, &pixPainter, this, TQRect(0, 0, pixSize.width(), pixSize.height()), colorGroup() );

  int m = 3;
  int tw = 0;
  int pw = 0;

  if ( m_pIcon ) {
    pw = m_pIcon->width();
    style().drawItem( &pixPainter, TQRect( m, 0, pw, pixSize.height() ),
                      AlignLeft | AlignVCenter,
                      colorGroup(), isEnabled(),
                      m_pIcon, TQString(), -1,
                      &g.buttonText());
  }

  if ( !text().isEmpty() ) {
    TQFontMetrics fm = fontMetrics();
    TQSize sz = fm.size( ShowPrefix, text() );
    tw = sz.width();
    int x = m + pw + (tw!=0 && pw!=0 ?m:0);
    TQString t = KStringHandler::rPixelSqueeze(text(), fm, pixSize.width() - (x + m + 22));

    style().drawItem( &pixPainter, TQRect( x, 0, tw, pixSize.height() ),
                      AlignLeft | AlignVCenter|ShowPrefix,
                      colorGroup(), isEnabled(),
                      0L, t, -1,
                      &g.buttonText());
  }


  TQPoint p1(pixSize.width() - 10, 0);
  TQPoint p2(pixSize.width() - 10, pixSize.height());
  qDrawShadeLine( &pixPainter, p1, p2, g, true, 0, 1 );

  p1 += TQPoint(2, 0);
  p2 += TQPoint(2, 0);
  qDrawShadeLine( &pixPainter, p1, p2, g, true, 0, 1 );

  if (m_bMouseOn) {
    int z = m_bClose ? 1:0;
    pixPainter.drawPixmap(pixSize.width() - 20 + z, (pixSize.height() - m_pClosePix->height()) / 2 + z, *m_pClosePix);
  }

  if(m_orientation == TQt::Vertical) {
    paint->drawPixmap(0, 0, pix);
  } else {
    paint->rotate(-90);
    paint->drawPixmap(1 - pixSize.width(), 0, pix);
  }
}

void DragBarButton::setIcon( const TQString& name )
{
  m_pIcon = new TQPixmap(BarIcon(name));
}

void DragBarButton::setPixmap( const TQPixmap& pixmap )
{
  m_pIcon = new TQPixmap(pixmap);
}

TQSize DragBarButton::sizeHint() const
{
  constPolish();
  int m = 3;
  int tw = 0;
  int th = 0;
  int pw = 0;
  int ph = 0;

  if ( !text().isEmpty() ) {
    TQFontMetrics fm = fontMetrics();
    TQSize sz = fm.size( ShowPrefix, text() );
    tw = 64; // Minimum size
    th = sz.height();
  }

  if ( m_pIcon ) {
    pw = m_pIcon->width();
    ph = m_pIcon->height();
  }

  int h = TQMAX(ph,th)+2*m;
  int w = m + pw + (tw!=0 && pw!=0 ?m:0) + tw + m + 22;

  TQSize size;
  
  if(m_orientation == TQt::Vertical) {
    size = TQSize(w, h).expandedTo(TQApplication::globalStrut());
  } else {
    size = TQSize(h, w).expandedTo(TQApplication::globalStrut());
  }
  
  return size;
}

void DragBarButton::mousePressEvent( TQMouseEvent* ev )
{
  m_bClose = false;
  TQRect closeRect;

  if(m_orientation == TQt::Vertical) {
    closeRect.setRect(width() - 20, 0, m_pClosePix->width(), height());
  } else {
    closeRect.setRect(0, 20 - m_pClosePix->width(), width(), m_pClosePix->width());
  }

  if ( closeRect.contains(ev->pos())) {
    m_bClose = true;
    repaint();
    return;
  }

  m_bPressed = true;
  m_ppoint = ev->pos();
}

void DragBarButton::mouseReleaseEvent( TQMouseEvent* ev )
{
  if ( m_bClose ) {
    m_bClose = false;
    repaint();
    TQRect closeRect;

    if(m_orientation == TQt::Vertical) {
      closeRect.setRect(width() - 20, 0, m_pClosePix->width(), height());
    } else {
      closeRect.setRect(0, 20 - m_pClosePix->width(), width(), m_pClosePix->width());
    }

    if ( closeRect.contains(ev->pos()))
    {
       kdDebug(43000) << "DragBarButton::mouseReleaseEvent() - Emitting closeRequest" << endl;
        emit closeRequired(this);
    }
    return;
  }

  m_bPressed = false;
  if (m_bDragged) {
    m_bDragged = false;
    emit finishDrag();
  } else {
    emit clicked();
  }
}

void DragBarButton::mouseMoveEvent( TQMouseEvent* ev )
{
  if (m_bPressed) {
    TQPoint p = m_ppoint;
    p -= ev->pos();
    if (p.manhattanLength() > 2 && !m_bDragged ) {
      m_bDragged = true;
      emit beginDrag();
    }
  }
}

void DragBarButton::enterEvent( TQEvent* ev )
{
  TQPushButton::enterEvent(ev);
  m_bMouseOn = true;
  repaint(false);
}

void DragBarButton::leaveEvent( TQEvent* ev )
{
  TQPushButton::leaveEvent(ev);
  m_bMouseOn = false;
  repaint();
}

void DragBarButton::setOrientation(TQt::Orientation orientation)
{
  m_orientation = orientation;
  
  if(m_orientation == TQt::Vertical) {
    setSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Fixed);
  } else {
    setSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Minimum);
  }
}

#include "stencilbarbutton.moc"
