/***************************************************************************
**
**  This file is part of SciFigs.
**
**  This library is free software; you can redistribute it and/or
**  modify it under the terms of the GNU Lesser General Public
**  License as published by the Free Software Foundation; either
**  version 2.1 of the License, or (at your option) any later version.
**
**  This file 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 Lesser General Public
**  License for more details.
**
**  You should have received a copy of the GNU Lesser General Public
**  License along with this library; if not, write to the Free Software
**  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2003-07-30
**  Copyright: 2003-2019
**    Marc Wathelet
**    Marc Wathelet (ULg, Liège, Belgium)
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include "TextEdit.h"
#include "GraphicObjectFactory.h"
#include "XMLSciFigs.h"
#include "TextEditProperties.h"
#include "SciFigsGlobal.h"

namespace SciFigs {

const QString TextEdit::xmlTextEditTag="TextEdit";

REGISTER_GRAPHICOBJECT(TextEdit, TextEdit::xmlTextEditTag,
                       QApplication::translate("TextEdit", "Text"),
                       QApplication::translate("TextEdit", "&Text"),
                       QApplication::translate("TextEdit", "Ctrl+T"),
                       QApplication::translate("TextEdit", "Display any text"))

/*!
  \class TextEdit TextEdit.h
  \brief The TextEdit is a text widget with uniform formatting and a mask that can be printed or exported to an image file.

*/

/*!
  \fn TextEdit::setTextAsData(bool b)

  Prevent from text changes when loading *.mkup files usefull for certain
  result sheets (e.g. geopsyhv).
*/

TextEdit::TextEdit(QWidget * parent) :
    GraphicObject(parent)
{
  TRACE;

  _text=tr("No text");
  _adjustBox=true;
  _textAsData=true;

  setTransparentMask(true);
  adjustSize();
}

TextEdit::~TextEdit()
{
  TRACE;
}

void TextEdit::paint(QPainter& p, double dotpercm, int, int, bool)
{
  TRACE;
  _font.setFont(p, dotpercm);
  //p.fillRect(0, 0, w, h, Qt::white);
  p.drawText(0, 0, INT_MAX, INT_MAX, Qt::AlignLeft | Qt::AlignTop, _text);
}

void TextEdit::setText(QString t)
{
  TRACE;
  _text=t;
  adjustSize();
  update();
}

void TextEdit::setAdjustBox(bool t)
{
  TRACE;
  _adjustBox=t;
  adjustSize();
  update();
}

void TextEdit::setFont(const QFont& f)
{
  _font=f;
  adjustSize();
  update();
}

void TextEdit::setFont(const QString& f)
{
  _font.fromString(f);
  adjustSize();
  update();
}

void TextEdit::setPrintSize(double dotpercm)
{
  if(_adjustBox) {
    int w, h;
    adjustSize(w, h);
    setPrintWidth((w+1)/dotpercm);
    setPrintHeight((h+1)/dotpercm);
  }
}

void TextEdit::adjustSize(int& width, int& height)
{
  TRACE;
  QRectF r=_font.boundingRect(_text);
  width=r.width();
  height=r.height();
  if(width<10) {
    width=10;
  }
  if(height<10) {
    height=10;
  }
}

void TextEdit::adjustSize()
{
  if(_adjustBox) {
    int w, h;
    adjustSize(w, h);
    if(w!=width() || h!=height()) {
      setPrintWidth(( w + 1)/SciFigsGlobal::screenResolution());
      setPrintHeight(( h + 1)/SciFigsGlobal::screenResolution());
      emit positionChanged();
      emit sizeChanged();
    }
  }
}

uint TextEdit::_category=PropertyProxy::uniqueId();
uint TextEdit::_tabFormat=PropertyProxy::uniqueId();

/*!
  Setup property editor
*/
void TextEdit::addProperties(PropertyProxy * pp)
{
  TRACE;
  GraphicObject::addProperties(pp);
  if( !pp->setCurrentCategory(_category) ) {
    pp->addCategory(_category, tr("Text"), QIcon( ":TextEdit.png"));
  }
  if(pp->setCurrentTab(_tabFormat)) {
    pp->addReference(this);
  } else {
    TextEditProperties * w=new TextEditProperties;
    pp->addTab(_tabFormat, tr("Format"), w, this);
  }
}

/*!
  Cleanup property editor
*/
void TextEdit::removeProperties(PropertyProxy * pp)
{
  TRACE;
  GraphicObject::removeProperties(pp);
  if(pp->setCurrentCategory(_category) ) {
    pp->removeTab(_tabFormat, this);
  }
}

void TextEdit::properties(PropertyWidget * w) const
{
  TRACE;
  if(w->id()==_tabFormat) {
    w->setValue(TextEditProperties::TextAsData, isTextAsData());
    w->setValue(TextEditProperties::Text, text());
    w->setValue(TextEditProperties::Font, _font.screenFont().toString());
    w->setValue(TextEditProperties::AdjustBox, adjustBox());
  } else {
    GraphicObject::properties(w);
  }
}

/*!
  Set value \a val to property \a id, after a user action in property editor
*/
void TextEdit::setProperty(uint wid, int pid, QVariant val)
{
  TRACE;
  if(wid==_tabFormat) {
    switch(pid) {
    case TextEditProperties::TextAsData:
      setTextAsData(val.toBool());
      break;
    case TextEditProperties::Text:
      setText(val.toString());
      break;
    case TextEditProperties::Font: {
        QFont f;
        if(f.fromString(val.toString())) {
          setFont(f);
        }
      }
      break;
    case TextEditProperties::AdjustBox:
      setAdjustBox(val.toBool());
      break;
    default:
      break;
    }
  } else {
    GraphicObject::setProperty(wid, pid, val);
  }
}

XMLMember TextEdit::xml_member(XML_MEMBER_ARGS)
{
  if(tag=="text") return XMLMember(0);
  else if(tag=="font") return XMLMember(1);
  else if(tag=="adjustBox") return XMLMember(2);
  else return GraphicObject::xml_member(tag, attributes, context)+3;
}

/*!
  text property may be considered as Make-up or data
  This test prevent from altering the text if it is considered as data in case of Make-up restore
*/
bool TextEdit::xml_setProperty(XML_SETPROPERTY_ARGS)
{
  switch(memberID) {
  case 0: {
      XMLSciFigs * scifigsContext=static_cast<XMLSciFigs *>(context);
      if(!scifigsContext->restoring() || !_textAsData || scifigsContext->data()) {
        _text=content.toString();
      }
    }
    return true;
  case 1:
    _font.fromString(content.toString());
    return true;
  case 2:
    _adjustBox=content.toBool();
    return true;
  default:
    return GraphicObject::xml_setProperty(memberID-3, tag, attributes, content, context);
  }
}

} // namespace SciFigs
