/***************************************************************************
 *   Copyright (C) 2004 by Hans Oischinger                                 *
 *   hans.oischinger@kdemail.net                                           *
 *                                                                         *
 *   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 Steet, Fifth Floor, Boston, MA 02110-1301, USA.             *
 ***************************************************************************/
#include "stopseditorwidget.h"

// Elements
#include "elements/stopelement.h"
#include "elements/gradient.h"
#include "elements/animatednumber.h"
#include "elements/number.h"
#include "elements/animatedcolorattr.h"
#include "elements/colorattribute.h"

// KDE
#include <kdebug.h>

#define STOPLABELWIDTH 11

StopsEditorWidget::StopsEditorWidget(QWidget *parent, const char *name)
    : QWidget(parent, name),
    m_gradient(0),
    m_selStop(0)
{
  m_stopsToLabels.setAutoDelete(true);
  setFixedHeight(STOPLABELWIDTH+2);
}


StopsEditorWidget::~StopsEditorWidget()
{}

void StopsEditorWidget::slotStopSelectionChanged( StopLabel* stopLbl )
{
  if (stopLbl == 0)
  {
    m_selStop = 0;
  }
  else
  {
    m_selStop = stopLbl->getStop();
  }
  emit(stopSelected(m_selStop));
}

void StopsEditorWidget::setGradient( Gradient *g )
{
  slotStopSelectionChanged(0);
  m_stopsToLabels.clear();
  m_gradient = g;

  // Create StopLabels for all children that are StopElements (usually all but we want to be sure)
  ElementNode* currentChild = m_gradient->getFirstChild();
  while (currentChild )
  {
    StopElement *stop = ::qt_cast<StopElement*>(currentChild);
    if ( stop )
    {
      createStopLabel( stop );
    }
    currentChild = currentChild->getNext();
  }
}

void StopsEditorWidget::resizeEvent( QResizeEvent *e )
{
  QWidget::resizeEvent(e);
  QPtrDictIterator<StopLabel> it(m_stopsToLabels);
  while( it.current() )
  {
    it.current()->reLayout();
    ++it;
  }
}

void StopsEditorWidget::slotStopModified( StopLabel *stopLbl )
{
  if (!stopLbl)
    return;
  emit (stopsModified(stopLbl->getStop()));
}

void StopsEditorWidget::slotStopModifiedFromOutside( StopElement *stop )
{
  if (!stop)
    return;

  blockSignals(true);
  StopLabel* stopLbl = m_stopsToLabels.find(stop);
  if (stopLbl)
  {
    stopLbl->syncToStop();
  }
  else
    kdWarning() << "StopsEditorWidget::slotStopModifiedFromOutside() - No Label found for stop" << endl;
  blockSignals(false);
}

void StopsEditorWidget::mousePressEvent( QMouseEvent * e )
{
  m_mousePos = e->pos();
}

void StopsEditorWidget::mouseReleaseEvent( QMouseEvent * e )
{
  if ( m_mousePos != e->pos() )
    return;

  // Create a new stop
  StopElement* stop = 0;
  if ( m_selStop )
    stop = static_cast<StopElement*>(m_selStop->clone());
  else
    stop = new StopElement();
  int maxX = width()-STOPLABELWIDTH;
  int offset = (int)(100. * (double)e->pos().x() / (double)maxX);
  stop->getOffset().baseVal() = Number(offset, Number::NUM_PERCENTAGE);

  m_gradient->appendChild( stop );
  createStopLabel(stop, true);
  emit (stopsModified(stop));
}

void StopsEditorWidget::createStopLabel( StopElement *stop, bool select )
{
  StopLabel *stopLabel = new StopLabel(stop, this);
  if ( !m_stopsToLabels.find(stop) )
    m_stopsToLabels.insert(stop, stopLabel);
  stopLabel->show();
  connect(stopLabel, SIGNAL(stopModified(StopLabel*)), this, SLOT(slotStopModified(StopLabel*)));
  connect(stopLabel, SIGNAL(selected(StopLabel* )),
          this, SLOT(slotStopSelectionChanged(StopLabel* )));
  if (select)
    emit (slotStopSelectionChanged(stopLabel));
}



#include <kcursor.h>

StopLabel::StopLabel( StopElement* element, StopsEditorWidget *parent ) :
    QLabel(parent),
    m_parentWidget(parent),
    m_stop(element),
    m_dragactive(false),
    m_xoffset(0)
{
  setLineWidth(1);
  setPaletteBackgroundColor( Qt::white );
  setFrameShape( QFrame::Box );
  setMouseTracking(true);
  setGeometry(0,0,STOPLABELWIDTH, STOPLABELWIDTH);
  syncToStop();
  connect (parent, SIGNAL(stopSelected(StopElement* )),
           this, SLOT(slotSelectionChanged(StopElement* )));
}

void StopLabel::mousePressEvent( QMouseEvent * e )
{
  m_mousePos = e->pos();
  // starting Drag
  m_dragactive = true;
  m_xoffset = e->pos().x();
  grabMouse();
  emit(selected(this));

  e->accept();
}

void StopLabel::mouseMoveEvent( QMouseEvent * e )
{
  int dragOffset = e->pos().x() - m_xoffset;
  int newX = x() + dragOffset;
  int maxX = parentWidget()->width()-STOPLABELWIDTH;
  if (newX<0)
    newX = 0;
  if (newX>maxX)
    newX = maxX;

  if( e->state() == LeftButton && m_dragactive )
  {
    setCursor(KCursor::sizeAllCursor());
    move( newX, 1 );
    updateStopToPosition();
  }
  else
    setCursor(KCursor::arrowCursor());

  e->accept();
}

void StopLabel::mouseReleaseEvent( QMouseEvent *e )
{
  if (m_dragactive &&  m_mousePos != e->pos())
  {
    updateStopToPosition();
    m_dragactive = false;
  }

  releaseMouse();
  e->accept();
}

void StopLabel::reLayout( )
{
  int newx = (int)(getStop()->getOffset().baseVal().floatValue()
                   * (double)(parentWidget()->width()-STOPLABELWIDTH));
  move(newx, 1);
  // kdDebug() << "StopLabel::reLayout() - New pos: " << x() << "," << y() << " " << width() << "x" << height() << endl;
}

void StopLabel::updateStopToPosition( )
{
  double xpercent = 100. * (double)x() / (double)(parentWidget()->width()-STOPLABELWIDTH);
  m_stop->getOffset().baseVal() = Number(xpercent, Number::NUM_PERCENTAGE);
  emit(stopModified(this));
}

void StopLabel::slotSelectionChanged( StopElement *s )
{
  if (m_stop != s)
    setPaletteForegroundColor(Qt::black);
  else
    setPaletteForegroundColor(Qt::white);
}

void StopLabel::syncToStop( )
{
  setBackgroundColor( m_stop->getStopColor().baseVal().qColor() );
  reLayout();
}





#include "stopseditorwidget.moc"
