#include "flagrowobj.h"

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

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

FlagRowObj::~FlagRowObj()
{
//    cout << "Destr FlagRowObj\n";
	flag.clear();
}

void FlagRowObj::init ()
{
    flag.setAutoDelete (true);
	parentRow=NULL;
	showFlags=true;
}

void FlagRowObj::copy (FlagRowObj* other)
{
    MapObj::copy(other);
	parentRow=other->parentRow;
	flag.clear();
	FlagObj *fo;
    for (fo=other->flag.first(); fo; fo=other->flag.next() )
		addFlag (fo);
}

void FlagRowObj::clone (FlagRowObj* pr)
{
	// Difference to copy:
	// We don't copy the flags here, they
	// are created on the fly by toggle and activate
	// This saves lots of canvas objects.
	MapObj::copy(pr);
	flag.clear();
	parentRow=pr;
}

void FlagRowObj::move(double x, double y)
{
    MapObj::move(x,y);
	int dx=0;
	FlagObj *fo;
    for (fo=flag.first(); fo; fo=flag.next() )
	{
		fo->move(x+dx,y);
		dx+=QSize(fo->getSize() ).width();
	}
}

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

void FlagRowObj::setVisibility (bool v)
{
	MapObj::setVisibility(v);
	FlagObj *fo;
	for (fo=flag.first(); fo; fo=flag.next() )
		fo->setVisibility (v);
}

FlagObj* FlagRowObj::addFlag (FlagObj *fo)
{
	FlagObj *newfo=new FlagObj (canvas);
	newfo->move (absPos.x() + bbox.width(), absPos.y() );
	newfo->copy (fo);	// create a deep copy of fo
	flag.append(newfo);
	calcBBoxSize();
	positionBBox();
	return newfo;
}

void FlagRowObj::positionBBox()
{
    bbox.moveTopLeft(absPos );
    clickBox.moveTopLeft(absPos );
}

void FlagRowObj::calcBBoxSize()
{
	QSize size(0,0);
	QSize boxsize(0,0);
	FlagObj *fo;
    for (fo=flag.first(); fo; fo=flag.next() )
	{
		size=fo->getSize();
		// add widths
		boxsize.setWidth(boxsize.width() + size.width() );
		// maximize height
		if (size.height() > boxsize.height() ) 
			boxsize.setHeight(size.height() );
	}
	bbox.setSize (boxsize);
	clickBox.setSize (boxsize);
}

QString FlagRowObj::getFlagName (const QPoint &p)
{
	if (!inBox (p)) return "";
	FlagObj *fo;
	for (fo=flag.first();fo; fo=flag.next() )
		if (fo->inBox (p)) return fo->getName();
	return "";	

	
}

bool FlagRowObj::isActive (const QString &foname)
{
	FlagObj *fo=findFlag (foname);
	if (parentRow && fo)
		return fo->isActive();
	else
		if (fo) return true;
	return false;
}

void FlagRowObj::toggle (const QString &foname, bool exclusive)
{
	FlagObj *fo=findFlag (foname);
	if (fo)
	{
		// FlagObj is here, it will be active, too.
		// Deactivate it by removing it from this row.
		flag.remove (fo);
	} else
	{
		// FlagObj is not present in this row.
		// Copy it from parentRow
		fo=parentRow->findFlag (foname);
		if (fo)
		{
			fo=addFlag (fo);
			fo->activate();
			if (exclusive) 
			{
				deactivateGroup (fo);
				updateToolbar();
			}
		} else
			qWarning ("FlagRowObj ("+name+")::toggle ("+foname+")  failed - could not find it in parentRow");
	}	
	calcBBoxSize();
	positionBBox();	
}

void FlagRowObj::activate (const QString &foname)
{
	// Note: "activate" is also called during loading of a map
	// Here we do not check for exclusive flags!
	FlagObj *fo=findFlag (foname);
	if (parentRow)
	{
		if (!fo)
		{
			// FlagObj is not present in this row.
			// Copy it from parentRow and activate there
			fo=parentRow->findFlag (foname);
			if (fo)
			{
				fo=addFlag (fo);
				fo->activate();
				if (showFlags) 
					fo->setVisibility (visible);
				else
					fo->setVisibility (false);
				calcBBoxSize();
			} else
				qWarning ("FlagRowObj ("+name+")::activate ("+foname+")  failed - could not find it in parentRow");
		}	
	} else
	{
		// I am the parentRow, mark flag as used
		if (fo)
		{
			fo->setUsed(true);
			fo->activate();
		}	
		else
			qWarning ("FlagRowObj::activate no FlagObj \""+foname+"\" found in parentRow");
	}
}


void FlagRowObj::deactivate (const QString &foname)
{
	FlagObj *fo=findFlag (foname);
	if (fo) flag.remove(fo);
	calcBBoxSize();
	positionBBox();
}

void FlagRowObj::deactivateAll ()
{
	if (!parentRow)
	{
		FlagObj *fo;
		for (fo=flag.first();fo; fo=flag.next() )
			fo->deactivate();
	} else
		qWarning ("FlagRowObj::deactivateAll mustn't be called for ordinary rows");
}

void FlagRowObj::deactivateGroup (FlagObj *keepfo)
{
	// deactivate all flags in keepof, but keep keepfo [sic!]
	if (keepfo)
	{
		QString g=keepfo->getGroup();
		if (g!="undefined")
		{
			FlagObj *fo;
			for (fo=flag.first();fo; fo=flag.next() )
				if (g==fo->getGroup() && keepfo!=fo) 
					flag.remove(fo);
		}		
	}	
}

void FlagRowObj::setEnabled (bool b)
{
	// If we have no parent, we are the default FlagRowObj
	// and have QToolbarButtons
	if (!parentRow)
	{
		FlagObj *fo;
		for (fo=flag.first();fo; fo=flag.next() )
			fo->setEnabled (b);
	}
}

void FlagRowObj::setShowFlags (bool b)
{
	showFlags=b;
}

void FlagRowObj::resetUsedCounter()
{
	FlagObj *fo;
	for (fo=flag.first();fo; fo=flag.next() )
		fo->setUsed (false);
}

QString FlagRowObj::saveToDir (const QString &tmpdir,const QString &prefix, bool writeflags)
{
	// Build xml string
	QString s;
	FlagObj *fo;
	if (parentRow)
		for (fo=flag.first();fo; fo=flag.next() )
		{
			// save flag to xml, if flag is set 
			s+=valueElement("standardflag",fo->getName() );

			// and tell parentRow, that this flag is used
			parentRow->activate(fo->getName() );
		}	
	else
		// Save icons to dir, if verbose is set (xml export)
		// and I am a parentRow 
		// and this flag is really used somewhere
		if (writeflags)
			for (fo=flag.first();fo; fo=flag.next() )
				if (fo->isUsed()) fo->saveToDir (tmpdir,prefix);
	return s;		

}

void FlagRowObj::setName (const QString &n)
{
	name=n;
}

void FlagRowObj::makeToolbar (QMainWindow *w, const QString &n)
{
	//Only make toolbar for the parentrow, not each row in branches
	if (!parentRow)
	{
		// create bar and buttons
		QToolBar* tb = new QToolBar( w);
		tb->setLabel (n);
		QAction *a;
		FlagObj *fo;
		for (fo=flag.first();fo; fo=flag.next() )
		{
			a=new QAction (
				fo->getToolTip(),
				fo->getPixmap(),
				fo->getName(),
				0,
				w,
				fo->getName()
			);
			a->setToggleAction(true);
			// FIXME should not be enabled by default, later in updateToolbar
			a->setEnabled(true);
			a->addTo (tb);
			fo->setButton (a);
			connect(a, SIGNAL( activated() ), 
					w, SLOT( standardFlagChanged() ) );
		}
	} else
		qWarning ("FlagRowObj::makeToolbar must not be called for ordinary rows");
}

void  FlagRowObj::updateToolbar()
{
	FlagObj *fo;
	if (parentRow)
	{
		// We are just a branch, not the toolbar default
		parentRow->deactivateAll();
		// In parentRow activate all existing (==active) flags
		for (fo=flag.first();fo; fo=flag.next() ) 
			parentRow->activate(fo->getName());
		parentRow->updateToolbar();	
	} else
	{
		// We are the toolbar default
		for (fo=flag.first();fo; fo=flag.next() ) 
			fo->updateButton();
	}
}

FlagObj* FlagRowObj::findFlag (const QString &name)
{
	FlagObj *fo;
	for (fo=flag.first();fo; fo=flag.next() )
	{
		if (fo->getName()==name) return fo;
	}
	return NULL;
}

