#include "headingobj.h"
#include <qregexp.h>

/////////////////////////////////////////////////////////////////
// HeadingObj
/////////////////////////////////////////////////////////////////
HeadingObj::HeadingObj() : MapObj()
{
//    cout << "Const HeadingObj ()\n";
    init ();
}

HeadingObj::HeadingObj(QCanvas* c) :MapObj(c)
{
//    cout << "Const HeadingObj\n";
    init ();
}

HeadingObj::~HeadingObj()
{
    textline.clear();
}

void HeadingObj::init()
{
    textline.setAutoDelete (TRUE);
    textwidth=40;
    color=QColor ("black");
    font=QFont();
	heading="";
}

void HeadingObj::copy(HeadingObj *other)
{
    MapObj::copy (other);
    textwidth=other->textwidth;
    color=other->color;
    font=other->font;
    setText (other->text() );
}

void HeadingObj::move(double x, double y)
{
    MapObj::move(x,y);

    int h;	// height of a textline
    int ho;	// offset of height while drawing all lines

    if (textline.first() )
		h=textline.first()->boundingRect().height();
    else
		h=2;
    QCanvasText *t;
    ho=0;
    for (t=textline.first(); t; t=textline.next() )
    {
		t->move(x,y+ho);
		ho=ho+h;
    }	
}


void HeadingObj::moveBy(double x, double y)
{
    move (x+absPos.x(),y+absPos.y() );
}

void HeadingObj::positionBBox()
{
    bbox.setX (absPos.x());
    bbox.setY (absPos.y());
}

void HeadingObj::calcBBoxSize()
{	
	int w=0;
	int h=0;
	// Using Backspace an empty heading might easily be created, then there
	// would be textline.first()==NULL This can be worked around by the following, but
	// then no selection would be visible, thus we prevent it in ::setText()
	if (!textline.isEmpty() )
	{
		QCanvasText *t;
		for (t=textline.first(); t; t=textline.next() )
		{
			h+=t->boundingRect().height();
			if (w<t->boundingRect().width() )
				w=t->boundingRect().width();
		}	
	} 
    bbox.setSize (QSize(w,h));
}

QCanvasText* HeadingObj::newLine(QString s)
{
    QCanvasText *t;
    t = new QCanvasText(canvas);
    t->setFont (font);
    t->setColor (color);
    t->setZ(Z_TEXT);
    t->setText(s);
	t->setTextFlags(Qt::AlignLeft);
    t->show();
    return t;
}

void HeadingObj::setText (QString s)
{
    heading=s;

    // remove old textlines and prepare generating new ones
    textline.clear();

	// prevent empty textline, so at least a small selection stays
	// visible for this heading
	if (s.length()==0) s="  ";

    int i=0;	// index for actual search for ws
    int j=0;	// index of last ws
	int k=0;	// index of "<br>" or similar linebreak
	int br=0;	// width of found break, e.g. for <br> it is 4
	QRegExp re("<br.*/>");
	re.setMinimal (true);

    // set the text and wrap lines
    while (s.length()>0)
    {
		// ok, some people wanted manual linebreaks, here we go
		k=re.search (s,i);
		if (k>=0)
		{
			br=re.cap(0).length();
			i=k;
		} else
			i=s.find (" ",i,false);
		if (i<0 && j==0)
		{   // no ws found at all in s
			// append whole s
			textline.append (newLine(s));
			s="";
		} else
		{
			if (i<0 && j>0)
			{	// no ws found in actual search
				if (s.length()<=textwidth)
				{
					textline.append (newLine(s));
					s="";
				} else
				{
					textline.append (newLine(s.left(j)));
					s=s.mid(j+1,s.length());
					j=0;
				}		    
			} else
			{
				if (i>= 0 && i<=static_cast <int> (textwidth))
				{   // there is a ws in textwidth
					if (br>0)
					{
						// here is a linebreak
						textline.append (newLine(s.left(i)));
						s=s.mid(i+br,s.length());
						i=0;
						j=0;
						br=0;
					} else
					{
						j=i;
						i++;
					}
				} else
				{
					if (i>static_cast <int> (textwidth)  )
					{	
						if (j>0)
						{   // a ws out of textwidth, but we have also one in
							textline.append (newLine(s.left(j)));
							s=s.mid(j+1,s.length());
							i=0;
							j=0;
						} else
						{   // a ws out of text, but none in
							textline.append (newLine(s.left(i)));
							s=s.mid(i+1,s.length());
							i=0;
						}
					}
				} 
			}	  
		}		    
    }
	setVisibility (visible);
	move (absPos.x(),absPos.y());
	calcBBoxSize();
}

QString HeadingObj::text ()
{
    return heading;
}

void HeadingObj::setFont (QFont f)
{
    if (font!=f) 
    {
		font=f;
		setText (text());
    }
}

QFont HeadingObj::getFont()
{
    return font;
}    
	
	
void HeadingObj::setColor (QColor c)
{
    if (color!=c)
    {
		color=c;
		QCanvasText *t;
		for (t=textline.first(); t; t=textline.next() )
			t->setColor(c);
    }	    
}

QColor HeadingObj::getColor()
{
    return color;
}    

void HeadingObj::setVisibility (bool v)
{
    MapObj::setVisibility(v);
    QCanvasText *t;
    for (t=textline.first(); t; t=textline.next() )
		if (v)
			t->show();
		else
			t->hide();
}

int HeadingObj::getHeight ()
{
	return bbox.height();
}

int HeadingObj::getWidth()
{
	return bbox.width();
}

