/***************************************************************************
 *   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.                                   *
 *                                                                         *
 *   copyright (C) 2002-2009                                               *
 *   Umbrello UML Modeller Authors <uml-devel@uml.sf.net>                  *
 ***************************************************************************/

// own header
#include "pinwidget.h"

// qt includes
#include <qpainter.h>

// kde includes
#include <klocale.h>
#include <kdebug.h>
#include <kinputdialog.h>

// app includes
#include "uml.h"
#include "umldoc.h"
#include "docwindow.h"
#include "umlview.h"
#include "uniqueid.h"
#include "listpopupmenu.h"
#include "floatingtextwidget.h"

//Added by qt3to4:
#include <QMouseEvent>
#include <QPolygon>

PinWidget::PinWidget(UMLView * view, UMLWidget* a, Uml::IDType id ): UMLWidget(view, id){

    init();
    m_pOw = a;
    int y = getY();
    m_nY = y;
    y = y < getMinY() ? getMinY() : y;
    m_nY = y;

    m_pName = new FloatingTextWidget(view,Uml::tr_Floating,"");
    view->setupNewWidget(m_pName);
    m_pName->setX(0);
    m_pName->setY(0);
    this->activate();
}

PinWidget::~PinWidget() {}

void PinWidget::init() {
    UMLWidget::setBaseType(Uml::wt_Pin);
    m_bIgnoreSnapToGrid = true;
    m_bIgnoreSnapComponentSizeToGrid = true;
    m_bResizable =  false ;
    m_pOw = NULL;
    m_nY = 0;
    setVisible(true);
}

void PinWidget::draw(QPainter & p, int offsetX, int offsetY) {
    int w = 10;
    int h = 10;
    int width_Activity = m_pOw->getWidth();
    int height_Activity = m_pOw->getHeight();
    int y = 0;
    int x = m_pOw->getX() + (width_Activity/2);

    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
    const int fontHeight  = fm.lineSpacing();
    int cas = 0;

    if ( (offsetY + height_Activity/2) <= m_pOw->getY() + height_Activity){
        y = m_pOw->getY()-5;
        if (m_pName->getX() == 0 && m_pName->getY() == 0) {
            //the floating text has not been linked with the signal
            m_pName->setX(x + 5 - m_Text.length()/2);
            m_pName->setY(y -fontHeight);
            cas = 1;
        }


    } else if((offsetY + height_Activity/2) > m_pOw->getY() + height_Activity){
       y = (m_pOw->getY() + height_Activity)-5;
        if (m_pName->getX() == 0 && m_pName->getY() == 0) {
            //the floating text has not been linked with the signal
            m_pName->setX(x + 5 - m_Text.length()/2);
            m_pName->setY(y + fontHeight);
            cas = 2;
        }
    }

    if (offsetX + width_Activity/4 <= m_pOw->getX() + width_Activity/2
         && (offsetY > m_pOw->getY() +5 && offsetY < m_pOw->getY() + height_Activity - 5) ){
        x = m_pOw->getX() -5;
        y = m_pOw->getY() + (height_Activity/2) -5;
        if (m_pName->getX() == 0 && m_pName->getY() == 0) {
            m_pName->setX(x - m_Text.length());
            m_pName->setY(y - fontHeight);
            cas = 3;
        }
    } else if (offsetX + width_Activity/4 > m_pOw->getX() + width_Activity/2
         && (offsetY > m_pOw->getY() +5 && offsetY < m_pOw->getY() + height_Activity - 5) ){
        x = m_pOw->getX() + width_Activity -5;
        y = m_pOw->getY() + (height_Activity/2) -5;
        if (m_pName->getX() == 0 && m_pName->getY() == 0) {
            //the floating text has not been linked with the signal
            m_pName->setX(x + 10);
            m_pName->setY(y - fontHeight);
            cas = 4;
        }
    }

    m_oldX = getX();
    setX(x);
    m_oldY = getY();
    setY(y);

//test if y isn't above the object
//     if ( y <= m_pOw[Uml::A]->getY() + height_Activity-5 && x == m_pOw[Uml::A]->getX() + (width_Activity/2) ) {
//         y = m_pOw[Uml::A]->getY() + height_Activity + 15;
//     }
//     if (y + h >= m_pOw[Uml::A]->getEndLineY()) {
//         y = m_pOw[Uml::A]->getEndLineY() - h;
//     }


    setPenFromSettings(p);
    if ( UMLWidget::getUseFillColour() ) {
        p.setBrush( UMLWidget::getFillColour() );
    }
    p.drawRect(x,y,w, h);
    //make sure it's always above the other
    setZ(20);
    setPenFromSettings(p);
    m_pName->setVisible(( m_pName->text().length() > 0 ));
    m_pName->updateComponentSize();
    if(m_bSelected)
         drawSelected(&p, offsetX, offsetY);
}

QSize PinWidget::calculateSize() {
    setSize(10,10);
    return QSize(10,10);
}

void PinWidget::setName(const QString &strName) {
    m_Text = strName;
    updateComponentSize();
    m_pName->setText(m_Text);
}

int PinWidget::getMinY() {
    if (!m_pOw) {
        return 0;
    }
    int heightA = m_pOw->getY() + m_pOw->getHeight();
    return heightA;
}

void PinWidget::mouseMoveEvent(QMouseEvent* me) {
    UMLWidget::mouseMoveEvent(me);
    int diffX = m_oldX - getX();
    int diffY = m_oldY - getY();
    if (m_pName!=NULL && !( m_pName->text() ).isEmpty()) {
        m_pName->setX(m_pName->getX() - diffX);
        m_pName->setY(m_pName->getY() - diffY);
    }
}

void PinWidget::slotMenuSelection(QAction* action) {
    bool ok = false;
    QString name = m_Text;

    ListPopupMenu::Menu_Type sel = m_pMenu->getMenuType(action);
    switch( sel ) {
    case ListPopupMenu::mt_Rename:
        name = KInputDialog::getText( i18n("Enter Pin Name"), i18n("Enter the pin name :"), m_Text, &ok );
        if( ok )
            setName(name);
        break;

    default:
        UMLWidget::slotMenuSelection(action);
    }
}


void PinWidget::saveToXMI( QDomDocument & qDoc, QDomElement & qElement ) {
    QDomElement PinElement = qDoc.createElement( "pinwidget" );
    PinElement.setAttribute( "widgetaid", ID2STR(m_pOw->id()) );
    UMLWidget::saveToXMI( qDoc, PinElement );
    if (m_pName && !m_pName->text().isEmpty()) {
        PinElement.setAttribute( "textid", ID2STR(m_pName->id()) );
        m_pName -> saveToXMI( qDoc, PinElement );
    }
    qElement.appendChild( PinElement );
}


bool PinWidget::loadFromXMI( QDomElement & qElement ) {
    if( !UMLWidget::loadFromXMI( qElement ) )
        return false;
    QString widgetaid = qElement.attribute( "widgetaid", "-1" );

    Uml::IDType aId = STR2ID(widgetaid);

    UMLWidget *pWA = m_pView -> findWidget( aId );
    if (pWA == NULL) {
        uDebug() << "role A object " << ID2STR(aId) << " not found";
        return false;
    }

    m_pOw = pWA;

    QString textid = qElement.attribute( "textid", "-1" );
    Uml::IDType textId = STR2ID(textid);
    if (textId != Uml::id_None) {
        UMLWidget *flotext = m_pView -> findWidget( textId );
        if (flotext != NULL) {
            // This only happens when loading files produced by
            // umbrello-1.3-beta2.
            m_pName = static_cast<FloatingTextWidget*>(flotext);
            //return true;
        }
    } else {
        // no textid stored -> get unique new one
        textId = UniqueID::gen();
    }

      //now load child elements
    QDomNode node = qElement.firstChild();
    QDomElement element = node.toElement();
    if ( !element.isNull() ) {
        QString tag = element.tagName();
        if (tag == "floatingtext") {
            m_pName = new FloatingTextWidget( m_pView,Uml::tr_Floating,m_Text, textId );
            if( ! m_pName->loadFromXMI(element) ) {
                // Most likely cause: The FloatingTextWidget is empty.
                delete m_pName;
                m_pName = NULL;
            }
        } else {
            uError() << "unknown tag " << tag << endl;
        }
    }

    return true;
}


#include "pinwidget.moc"

