/* text.cc
 * This file belongs to Worker, a file manager for UN*X/X11.
 * Copyright (C) 2001-2024 Ralf Hoffmann.
 * You can contact me at: ralf@boomerangsworld.de
 *   or http://www.boomerangsworld.de/worker
 *
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "text.h"
#include "lowlevelfunc.h"
#include "awindow.h"
#include "drawablecont.hh"

const char *Text::type="Text";

Text::Text( AGUIX *taguix, int tx, int ty, const char *ttext, enum center_mode center_mode )
    : GUIElement( taguix )
{
  this->text=dupstring(ttext);
  _x=tx;
  _y=ty;
  _w = taguix->getTextWidth( ttext ) + 1;
  _h=taguix->getCharHeight();
  this->color = _aguix->getFaceCol_default_fg();
  bgset=false;
  font=NULL;
  bg = 0;
  ownbg = false;

  m_shrinker_buf.current_width = -1;

  m_center_mode = center_mode;
}

Text::Text( AGUIX *taguix, int tx, int ty, const char *ttext, int tfg, int tbg, enum center_mode center_mode )
    : GUIElement( taguix )
{
  this->text = dupstring( ttext );
  _x = tx;
  _y = ty;
  _w = taguix->getTextWidth( ttext ) + 1;
  _h = taguix->getCharHeight();
  this->color = tfg;
  bgset = false;
  font = NULL;
  bg = tbg;
  ownbg = true;

  m_shrinker_buf.current_width = -1;

  m_center_mode = center_mode;
}

Text::~Text()
{
  if(text!=NULL) _freesafe(text);
}

const char *Text::getText() const
{
  return text;
}

void Text::setText( const char *new_text )
{
    m_shrinker_buf.current_width = -1;
    
    if ( text != NULL ) _freesafe( text );
    text = dupstring( new_text );

    //TODO we could also use a flag to avoid resizing
    if ( m_shrinker.get() == NULL ) {
        _w = _aguix->getTextWidth( text, font ) + 1;
        if ( isCreated() == true ) {
            _parent->resizeSubWin( win, _w, _h );
        }
    }
    redraw();
}

int Text::getColor() const
{
  return color;
}

void Text::setColor(int tcolor)
{
    if ( tcolor < _aguix->getNumberOfColorsForType( AGUIXColor::USER_COLOR ) && tcolor >= 0 ) {
        this->color = tcolor;
        redraw();
    }
}

void Text::redraw()
{
  if ( isCreated() == true ) {
    if ( bgset == false ) {
      if ( ownbg == true ) {
	_aguix->SetWindowBG( win, bg );
      } else {
	_aguix->SetWindowBG( win, _parent->getBG() );
      }
      bgset = true;
    }
    _aguix->ClearWin(win);

    DrawableCont dc( _aguix, win );

    int y = 0;

    if ( m_center_mode & CENTER_VERTICALLY ) {
        int th;
        
        if ( font ) {
            th = font->getCharHeight();
        } else {
            th = _aguix->getCharHeight();
        }

        y = getHeight() / 2 - th / 2;
    }

    if ( m_shrinker.get() != NULL ) {
        if ( m_shrinker_buf.current_width != getWidth() ) {
            AFontWidth len_calc( _aguix, font );

            m_shrinker_buf.current_text = m_shrinker->shrink( text, getWidth(), len_calc );
            m_shrinker_buf.current_width = getWidth();
        }
        _aguix->DrawText( dc, font, m_shrinker_buf.current_text.c_str(), 0, y, color );
    } else {
        _aguix->DrawText( dc, font, text, 0, y, color );
    }
  }
}

void Text::flush()
{
}

bool Text::handleMessage(XEvent *E,Message *msg)
{
  if ( isCreated() == false ) return false;
  if((msg->type==Expose)&&(msg->window==win)) {
    redraw();
  }
  return false;
}

int Text::setFont( const char *fontname )
{
  m_shrinker_buf.current_width = -1;

  font=_aguix->getFont(fontname);
  if(font==NULL) return -1;
  _w = _aguix->getTextWidth( text, font ) + 1;
  _h=font->getCharHeight();
  if ( isCreated() == true ) {
    _parent->resizeSubWin(win,_w,_h);
  }
  return 0;
}

const char *Text::getType() const
{
  return type;
}

bool Text::isType(const char *qtype) const
{
  if(strcmp(type,qtype)==0) return true;
  return false;
}

void Text::setBG( int tcolor )
{
    if ( tcolor < _aguix->getNumberOfColorsForType( AGUIXColor::USER_COLOR ) && tcolor >= 0 ) {
        bg = tcolor;
        ownbg = true;
        bgset = false;
        redraw();
    }
}

int Text::getBG() const
{
  return bg;
}

void Text::setFG( int tcolor )
{
  setColor( tcolor );
}

int Text::getFG() const
{
  return color;
}

void Text::setTextShrinker( RefCount<TextShrinker> shrinker )
{
    m_shrinker = shrinker;
    m_shrinker_buf.current_width = -1;
}
