/* ============================================================
 * Copyright 2004 by Tudor Calin <tudor@1xtech.com>

 * 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, 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.
 * 
 * ============================================================ */
// TQt
#include <tqpixmap.h>
#include <tqfont.h>
#include <tqfontmetrics.h>
#include <tqpalette.h>
#include <tqpainter.h>
#include <tqevent.h>
#include <tqtextedit.h>
// Local
#include "thumbview.h"
#include "thumbitem.h"

namespace KIPIKameraKlientPlugin
{

class ThumbItemLineEdit : public TQTextEdit {

public:
    ThumbItemLineEdit(const TQString& text, TQWidget* parent, ThumbItem* item);

private:
    void keyPressEvent(TQKeyEvent *e);
    void focusOutEvent(TQFocusEvent *e);
    ThumbItem *thumbItem;
    TQString    startText;
};

ThumbItemLineEdit::ThumbItemLineEdit(const TQString& text, TQWidget* parent, ThumbItem* item)
    : TQTextEdit(parent), thumbItem(item), startText(text) {
    setFrameStyle(TQFrame::Plain | TQFrame::Box);
    setLineWidth(1);

    setHScrollBarMode( AlwaysOff );
    setVScrollBarMode( AlwaysOff );

    setWordWrap( WidgetWidth );
    setWrapColumnOrWidth(item->pixmapRect().width());
    resize(200, 200);
    setText(text);
    setAlignment(TQt::AlignCenter);
    resize(wrapColumnOrWidth() + 2, heightForWidth(wrapColumnOrWidth()) + 2);
}

void ThumbItemLineEdit::keyPressEvent( TQKeyEvent *e ) {
    if ( e->key()  == Key_Escape) {
		thumbItem->setText(startText);
		thumbItem->cancelRenameItem();
    } else if ( e->key() == Key_Enter || e->key() == Key_Return ) {
		thumbItem->renameItem();
    } else {
		TQTextEdit::keyPressEvent( e );
		sync();
    }
}

void ThumbItemLineEdit::focusOutEvent( TQFocusEvent *e ) {
    if (e->reason() != TQFocusEvent::Popup ) {
		thumbItem->cancelRenameItem();
	}
}

class ThumbItemPrivate {

	public:
		TQString text;
		TQPixmap* pixmap;

		TQRect rect;
		TQRect textRect;
		TQRect pixmapRect;

		bool selected;
		TQString    key;
};

ThumbItem::ThumbItem(ThumbView* parent, const TQString& text, const TQPixmap& pixmap) {
    view = parent;
    next = 0;
    prev = 0;
    renameBox = 0;

    d = new ThumbItemPrivate;
    d->text = text;
    d->pixmap = new TQPixmap(pixmap);
    d->selected = false;
    d->key = d->text;
    // make sure to calcrect before inserting; this will calculate the size of the rect; inserting would move it to the required location
    d->rect       = TQRect(0, 0, 0, 0);
    d->textRect   = TQRect(0, 0, 0, 0);
    d->pixmapRect = TQRect(0, 0, 0, 0);
    calcRect();

    view->insertItem(this);
}

ThumbItem::~ThumbItem() {
    view->takeItem(this);
    delete d->pixmap;
    delete d;
}

void ThumbItem::calcRect() {
    TQRect rect(d->rect);
    TQRect textRect(d->textRect);
    TQRect pixmapRect(d->pixmapRect);
    // set initial pixrect
    int pw = d->pixmap->width();
    int ph = d->pixmap->height();

    pixmapRect.setWidth(pw);
    pixmapRect.setHeight(ph);
    // word wrap
    TQFontMetrics fm(view->font());
    TQRect r = TQRect(fm.boundingRect(0, 0, pixmapRect.width(),
                                    0xFFFFFFFF, TQt::AlignHCenter |
                                    TQt::WordBreak | TQt::BreakAnywhere,
                                    d->text));
    r.setWidth(r.width() + 4);

    textRect.setWidth(r.width());
    textRect.setHeight(r.height());
    // Now start updating the rects
    int w = TQMAX(textRect.width(), pixmapRect.width());
    int h = textRect.height() + pixmapRect.height() + 1;

    rect.setWidth(w);
    rect.setHeight(h);
    // Center the pix and text rect
    pixmapRect = TQRect((rect.width() - pixmapRect.width())/2,
                       0,
                       pixmapRect.width(), pixmapRect.height());
    textRect   = TQRect((rect.width() - textRect.width())/2,
                       rect.height() - textRect.height(),
                       textRect.width(), textRect.height());
    // Finally save the settings
    setRect(rect);
    setPixmapRect(pixmapRect);
    setTextRect(textRect);
}

void ThumbItem::paintItem(TQPainter *, const TQColorGroup& cg) {
    TQRect pRect=pixmapRect(true);
    TQRect tRect=textRect(true);

    TQPixmap pix(rect().width(), rect().height());
    pix.fill(cg.base());
    TQPainter painter(&pix);
    painter.drawPixmap(pRect.x(), pRect.y(), *pixmap() );
    if (isSelected()) {
        TQPen pen;
        pen.setColor(cg.highlight());
        painter.setPen(pen);
        painter.drawRect(0, 0, pix.width(), pix.height());
        painter.fillRect(0, tRect.y(), pix.width(),
                     tRect.height(), cg.highlight() );
        painter.setPen( TQPen( cg.highlightedText() ) );
    } else {
        painter.setPen( cg.text() );
	}
    painter.drawText(tRect, TQt::WordBreak|TQt::BreakAnywhere|TQt::AlignHCenter|TQt::AlignTop,text());

    painter.end();

    TQRect r(rect());
    r = TQRect(view->contentsToViewport(TQPoint(r.x(), r.y())), TQSize(r.width(), r.height()));

    bitBlt(view->viewport(), r.x(), r.y(), &pix, 0, 0, r.width(), r.height());
}

void ThumbItem::repaint() {
    TQRect r(view->contentsRectToViewport(d->rect));
    view->viewport()->repaint(r);
}

TQRect ThumbItem::rect() {
    return d->rect;
}

TQRect ThumbItem::textRect(bool relative) {
    if (relative) {
        return d->textRect;
    } else {
        TQRect r(x() + d->textRect.x(), y() + d->textRect.y(), d->textRect.width(), d->textRect.height());
        return r;
    }
}

TQRect ThumbItem::pixmapRect(bool relative) {
    if (relative) {
        return d->pixmapRect;
    } else {
        TQRect r(x() + d->pixmapRect.x(), y() + d->pixmapRect.y(), d->pixmapRect.width(), d->pixmapRect.height());
        return r;
    }

}

void ThumbItem::setRect(const TQRect& rect) {
	if (rect.isValid()) {
        d->rect = rect;
    }
}

void ThumbItem::setTextRect(const TQRect& rect)
{
   if (rect.isValid()) {
        d->textRect = rect;
    }
}

void ThumbItem::setPixmapRect(const TQRect& rect) {
	if (rect.isValid()) {
        d->pixmapRect = rect;
    }
}

TQPixmap * ThumbItem::pixmap() const {
    return d->pixmap;
}

TQString ThumbItem::text() const {
    return d->text;
}

int ThumbItem::x() const {
    return d->rect.x();
}

int ThumbItem::y() const {
    return d->rect.y();
}

int ThumbItem::width() const {
    return d->rect.width();
}

int ThumbItem::height() const {
    return d->rect.height();
}

bool ThumbItem::move(int x, int y) {
    if (x == this->x() && y == this->y()) {
		return false;
	}
    d->rect.setRect(x, y, d->rect.width(), d->rect.height());
    return true;
}

void ThumbItem::setSelected(bool val, bool cb) {
    if (cb) {
        view->blockSignals(true);
        view->clearSelection();
        view->blockSignals(false);
    }
    d->selected = val;
    view->selectItem(this, val);
    TQRect r(d->rect);
    r = TQRect(view->contentsToViewport(TQPoint(r.x(), r.y())), TQSize(r.width(), r.height()));
    view->viewport()->update(r);
}

bool ThumbItem::isSelected() {
    return d->selected;
}

void ThumbItem::setPixmap(const TQPixmap& pixmap) {
    if (d->pixmap) {
        delete d->pixmap;
        d->pixmap = 0;
    }
    d->pixmap = new TQPixmap(pixmap);

    TQRect oR(d->rect);
    calcRect();
    oR = oR.unite(d->rect);
    oR = TQRect(view->contentsToViewport(TQPoint(oR.x(), oR.y())), TQSize(oR.width(), oR.height()));

    view->updateItemContainer(this);

    if(oR.intersects(TQRect(view->contentsX(), view->contentsY(), view->visibleWidth(), view->visibleHeight()))) {
        view->viewport()->repaint(oR);
	}
}

void ThumbItem::setText(const TQString& text) {
    d->text = text;
    d->key  = text;

    TQRect oR(d->rect);
    calcRect();
    oR = oR.unite(d->rect);
    oR = TQRect(view->contentsToViewport(TQPoint(oR.x(), oR.y())),
               TQSize(oR.width(), oR.height()));

    view->updateItemContainer(this);
    
    if(oR.intersects(TQRect(view->contentsX(), view->contentsY(), view->visibleWidth(), view->visibleHeight()))) {
        view->viewport()->repaint(oR);
	}
}

ThumbItem * ThumbItem::nextItem() {
    return next;
}

ThumbItem * ThumbItem::prevItem() {
    return prev;
}

ThumbView* ThumbItem::iconView() {
    return view;    
}

void ThumbItem::rename() {
    if (renameBox) {
        delete renameBox;
        renameBox = 0;
    }
    renameBox = new ThumbItemLineEdit(d->text, view->viewport(), this);
    TQRect tr(textRect(false));
    view->addChild(renameBox, tr.x() + (tr.width()/2 - renameBox->width()/2 ), tr.y() - 3);
    renameBox->selectAll();
    view->viewport()->setFocusProxy(renameBox);
    renameBox->setFocus();
    renameBox->show();

    view->renamingItem = this;
}

void ThumbItem::renameItem() {
    if (!renameBox) {
		return;
	}
    setText(renameBox->text());

    bool resetFocus = view->viewport()->focusProxy() == renameBox;
    delete renameBox;
    renameBox = 0;
    if (resetFocus) {
		view->viewport()->setFocusProxy(view);
		view->setFocus();
    }
    view->renamingItem = 0;
    view->emitRenamed(this);
}

void ThumbItem::cancelRenameItem() {
    repaint();

    bool resetFocus = view->viewport()->focusProxy() == renameBox;
    delete renameBox;
    renameBox = 0;
    if (resetFocus) {
		view->viewport()->setFocusProxy(view);
		view->setFocus();
    }
    view->renamingItem = 0;
}

int ThumbItem::compare(ThumbItem *item) {
    return key().localeAwareCompare(item->key());
}

TQString ThumbItem::key() const {
    return d->key;    
}

}  // NameSpace KIPIKameraKlientPlugin
