#include <qcanvas.h>
#include <qapplication.h>
#include <qstringlist.h>
#include <qstring.h>
#include <qpainter.h>
#include "canvbox.h"
#include "mycanvas.h"
#include "creportitem.h"

//CanvasBox class

void CanvasBox::scale(int scale)
{
    setSize(width()*scale, height()*scale);
}

void CanvasBox::draw(QPainter &painter)
{
    QCanvasRectangle::draw(painter);
}


//CanvasSection class

void CanvasSection::draw(QPainter &painter)
{
    CanvasBox::draw(painter);
}


//CanvasKugarTemplate class

CanvasKugarTemplate::CanvasKugarTemplate(int x, int y, int width, int height, QCanvas * canvas):
	CanvasSection(x, y, width, height, canvas)
{
    detailsCount = 0;

    setZ(1);
    ((MyCanvas *)canvas)->templ = this;
    reportHeader = 0;
    reportFooter = 0;
    pageHeader = 0;
    pageFooter = 0;
    
    pair<QString, QStringList> propValues;
    
    propValues.first = "0";
    propValues.second << qApp->translate("CanvasKugarTemplate", "Page size");
    propValues.second << "int_from_list";
    propValues.second << "0 - A4" << "1 - B5" << "2 - Letter" 
	    << "3 - Legal" << "4 - Executive" << "5 - A0" 
	    << "6 - A1" << "7 - A2" << "8 - A3" << "9 - A5"
	    << "10 - A6" << "11 - A7" << "12 - A8"
	    << "13 - A9" << "14 - B0" << "15 - B1" << "16 - B10"
	    << "17 - B2" << "18 - B3" << "19 - B4" << "20 - B6"
	    << "21 - B7" << "22 - B8" << "23 - B9" << "24 - C5E"
	    << "25 - Comm10E" << "26 - DLE" << "27 - Folio"
	    << "28 - Ledger" << "29 - Tabloid" << "30 - NPageSize";
    props["PageSize"] = propValues;
    propValues.second.clear();
    
    propValues.first = "0";
    propValues.second << qApp->translate("CanvasKugarTemplate", "Page orientation");
    propValues.second << "int_from_list";
    propValues.second << qApp->translate("CanvasKugarTemplate", "0 - Portrait");
    propValues.second << qApp->translate("CanvasKugarTemplate", "1 - Landscape");
    props["PageOrientation"] = propValues;
    propValues.second.clear();
    
    propValues.first = "0";
    propValues.second << qApp->translate("CanvasKugarTemplate", "Top margin");
    propValues.second << "int";
    props["TopMargin"] = propValues;
    propValues.second.clear();
    
    propValues.first = "0";
    propValues.second << qApp->translate("CanvasKugarTemplate", "Bottom margin");
    propValues.second << "int";
    props["BottomMargin"] = propValues;
    propValues.second.clear();
    
    propValues.first = "0";
    propValues.second << qApp->translate("CanvasKugarTemplate", "Left margin");
    propValues.second << "int";
    props["LeftMargin"] = propValues;
    propValues.second.clear();
    
    propValues.first = "0";
    propValues.second << qApp->translate("CanvasKugarTemplate", "Right margin");
    propValues.second << "int";
    props["RightMargin"] = propValues;
    propValues.second.clear();
}

CanvasKugarTemplate::~CanvasKugarTemplate()
{
    if (reportHeader)
	delete reportHeader;
    if (pageHeader)
	delete pageHeader;
    
    map<int, DetailBand>::const_iterator it;
    for (it = details.begin(); it != details.end(); ++it)
    {
	if (it->second.first.first)
	    delete it->second.first.first;
	if (it->second.second)
	    delete it->second.second;
	if (it->second.first.second)
	    delete it->second.first.second;
    }    
    if (pageFooter)
	delete pageFooter;
    if (reportFooter)
	delete reportFooter;
}

void CanvasKugarTemplate::draw(QPainter &painter)
{
    painter.setPen(QColor(0, 0, 0));
    QPoint p1((int)(x()+props["LeftMargin"].first.toInt()),
	      (int)(y()+props["TopMargin"].first.toInt()));
    QPoint p2((int)(x()+props["LeftMargin"].first.toInt()),
	      (int)y() + height() - props["BottomMargin"].first.toInt());
    QPoint p3((int)x() + width() - props["RightMargin"].first.toInt(),
	      (int)y() + height() - props["BottomMargin"].first.toInt());
    QPoint p4((int)x() + width() - props["RightMargin"].first.toInt(),
	      (int)(y()+props["TopMargin"].first.toInt()));
    painter.moveTo(p1);
    painter.lineTo(p2);
    painter.lineTo(p3);
    painter.lineTo(p4);
    painter.lineTo(p1);
/*    painter.drawRect((int)(x()+props["LeftMargin"].first.toInt()),
		     (int)(y()+props["TopMargin"].first.toInt()),
		     width() - props["LeftMargin"].first.toInt() - props["RightMargin"].first.toInt(),
		     height() - props["TopMargin"].first.toInt() - props["BottomMargin"].first.toInt());*/
    CanvasSection::draw(painter);
}

/*arrange sections on page automatically*/
void CanvasKugarTemplate::arrangeSections(bool destructive)
{
    int base = props["TopMargin"].first.toInt();
    if (reportHeader)
    {
	reportHeader->arrange(base, destructive);
	base += reportHeader->props["Height"].first.toInt();
	reportHeader->show();
    }
    if (pageHeader)
    {
	pageHeader->arrange(base, destructive);
	base += pageHeader->props["Height"].first.toInt();
	pageHeader->show();
    }
    
    map<int, DetailBand>::const_iterator it;
    for (it = details.begin(); it != details.end(); ++it)
    {
	//arranging detail header
	if (it->second.first.first)
	{
	    it->second.first.first->arrange(base, destructive);
	    base += it->second.first.first->props["Height"].first.toInt();
	    it->second.first.first->show();
	}
	//arranging detail
	if (it->second.second)
	{
	    it->second.second->arrange(base, destructive);
	    base += it->second.second->props["Height"].first.toInt();
	    it->second.second->show();
	}
    }
    map<int, DetailBand>::reverse_iterator itr;
    for (itr = details.rbegin(); itr != details.rend(); ++itr)
    {
	//arranging detail footer
	if (itr->second.first.second)
	{
	    itr->second.first.second->arrange(base, destructive);
	    base += itr->second.first.second->props["Height"].first.toInt();
	    itr->second.first.second->show();
	}
    }
    
    if (pageFooter)
    {
	pageFooter->arrange(base, destructive);
	base += pageFooter->props["Height"].first.toInt();
	pageFooter->show();
    }
    if (reportFooter)
    {
	reportFooter->arrange(base, destructive);
	base += reportFooter->props["Height"].first.toInt();
	reportFooter->show();
    }
}

QString CanvasKugarTemplate::getXml()
{
    QString result = "";
    result += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
    result += "<KugarTemplate";
    for (map<QString, pair<QString, QStringList> >::const_iterator it = props.begin();
        it != props.end(); it++ )
    {
	result += " " + it->first + "=" + "\"" + it->second.first + "\"";
    }
    result += ">\n";
    
    if (reportHeader)
	result += reportHeader->getXml();
    if (pageHeader)
	result += pageHeader->getXml();
    
	//map<int, DetailBand>::const_iterator it;
    for (map<int, DetailBand>::const_iterator it = details.begin(); it != details.end(); ++it)
    {
	//getting xml from detail header
	if (it->second.first.first)
	    result += it->second.first.first->getXml();
	//getting xml from detail
	if (it->second.second)
	    result += it->second.second->getXml();
	//getting xml from detail footer
	if (it->second.first.second)
	    result += it->second.first.second->getXml();
    }    
    if (pageFooter)
	result += pageFooter->getXml();
    if (reportFooter)
	result += reportFooter->getXml();
    
    result += "</KugarTemplate>\n";
    
    return result;
}

void CanvasKugarTemplate::removeSection(CanvasBand *section,
	CanvasDetailHeader **header, CanvasDetailFooter **footer)
{
    *header = 0;
    *footer = 0;
    if (section == reportHeader)
	reportHeader = 0;
    if (section == reportFooter)
	reportFooter = 0;
    if (section == pageHeader)
	pageHeader = 0;
    if (section == pageFooter)
	pageFooter = 0;
    for (map<int, DetailBand>::iterator i = details.begin(); i != details.end(); i++)
    {
	if (i->second.second == section)
	{
	    //delete not only detail but it's header and footer
	    i->second.second = 0;
	    *header = i->second.first.first;
	    i->second.first.first = 0;
	    *footer = i->second.first.second;
	    i->second.first.second = 0;
	    detailsCount--;
	    detailsCount < 0 ? detailsCount = 0 : detailsCount=detailsCount;
	}
	if (i->second.first.first == section)
	    i->second.first.first = 0;
	if (i->second.first.second == section)
	    i->second.first.second = 0;
    }
}


//CanvasBand class 

void CanvasBand::draw(QPainter &painter)
{
    setSize(((MyCanvas*)canvas())->templ->width()
	    - ((MyCanvas*)canvas())->templ->props["RightMargin"].first.toInt()
	    - ((MyCanvas*)canvas())->templ->props["LeftMargin"].first.toInt(),
	    props["Height"].first.toInt());
    CanvasSection::draw(painter);
}

//arrange band and all sublings (items)
void CanvasBand::arrange(int base, bool destructive)
{
    int diff = base - (int)y();
    setY(base);
    if (!destructive)
	return;
    for (QCanvasItemList::Iterator it=items.begin(); it!=items.end(); ++it)
    {
	(*it)->moveBy(0, diff);
	( (CanvasReportItem *)(*it) )->updateGeomProps();
	canvas()->update();
    }
}

QString CanvasBand::getXml()
{
    QString result = "";
    map<QString, pair<QString, QStringList> >::const_iterator it;
    for (it = props.begin(); it != props.end(); ++it)
    {
	result += " " + it->first + "=" + "\"" + it->second.first + "\"";
    }
    result += ">\n";
    for (QCanvasItemList::Iterator it=items.begin(); it!=items.end(); ++it)
    {
	result += ((CanvasReportItem *)(*it))->getXml();
    }
    return result;
}

CanvasBand::~CanvasBand()
{
    for (QCanvasItemList::Iterator it = items.begin(); it != items.end(); ++it)
    {
//	(*it)->hide();
	delete (*it);
    }
    items.clear();
}

//CanvasReportHeader class

CanvasReportHeader::CanvasReportHeader(int x, int y, int width, int height, QCanvas * canvas):
	CanvasBand(x, y, width, height, canvas)
{
    pair<QString, QStringList> propValues;
    
    propValues.first = "50";
    propValues.second = "Report header's height";
    propValues.second << "int";
    props["Height"] = propValues;
    propValues.second.clear();
};

void CanvasReportHeader::draw(QPainter &painter)
{
    painter.drawText(rect(), AlignVCenter | AlignLeft,
		     qApp->translate("CanvasReportHeader", "Report Header"));
    CanvasBand::draw(painter);
}

QString CanvasReportHeader::getXml()
{
    return "\t<ReportHeader" + CanvasBand::getXml() + "\t</ReportHeader>\n\n";
}


//CanvasReportFooter class

CanvasReportFooter::CanvasReportFooter(int x, int y, int width, int height, QCanvas * canvas):
	CanvasBand(x, y, width, height, canvas)
{
    pair<QString, QStringList> propValues;
    
    propValues.first = "50";
    propValues.second = "Report footer's height";
    propValues.second << "int";
    props["Height"] = propValues;
    propValues.second.clear();
}

void CanvasReportFooter::draw(QPainter &painter)
{
    painter.drawText(rect(), AlignVCenter | AlignLeft,
		     qApp->translate("CanvasReportFooter", "Report Footer"));
    CanvasBand::draw(painter);
}

QString CanvasReportFooter::getXml()
{
    return "\t<ReportFooter" + CanvasBand::getXml() + "\t</ReportFooter>\n\n";
}


//CanvasPageHeader class

CanvasPageHeader::CanvasPageHeader(int x, int y, int width, int height, QCanvas * canvas):
	CanvasBand(x, y, width, height, canvas)
{
    pair<QString, QStringList> propValues;
    
    propValues.first = "50";
    propValues.second = "Page header's height";
    propValues.second << "int";
    props["Height"] = propValues;
    propValues.second.clear();
}

void CanvasPageHeader::draw(QPainter &painter)
{
    painter.drawText(rect(), AlignVCenter | AlignLeft,
		     qApp->translate("CanvasPageHeader", "Page Header"));
    CanvasBand::draw(painter);
}

QString CanvasPageHeader::getXml()
{
    return "\t<PageHeader" + CanvasBand::getXml() + "\t</PageHeader>\n\n";
}


//CanvasReportFooter class

CanvasPageFooter::CanvasPageFooter(int x, int y, int width, int height, QCanvas * canvas):
	CanvasBand(x, y, width, height, canvas)
{
    pair<QString, QStringList> propValues;
    
    propValues.first = "50";
    propValues.second = "Page footer's height";
    propValues.second << "int";
    props["Height"] = propValues;
    propValues.second.clear();
}

void CanvasPageFooter::draw(QPainter &painter)
{
    painter.drawText(rect(), AlignVCenter | AlignLeft,
		     qApp->translate("CanvasPageFooter", "Page Footer"));
    CanvasBand::draw(painter);
}

QString CanvasPageFooter::getXml()
{
    return "\t<PageFooter" + CanvasBand::getXml() + "\t</PageFooter>\n\n";
}


//CanvasDetailHeader class

CanvasDetailHeader::CanvasDetailHeader(int x, int y, int width, int height, QCanvas * canvas):
	CanvasBand(x, y, width, height, canvas)
{
    pair<QString, QStringList> propValues;
    
    propValues.first = "50";
    propValues.second = "Detail header's height";
    propValues.second << "int";
    props["Height"] = propValues;
    propValues.second.clear();
    
    propValues.first = "0";
    propValues.second = "Detail header's level";
    propValues.second << "int";
    props["Level"] = propValues;
    propValues.second.clear();

}

void CanvasDetailHeader::draw(QPainter &painter)
{
    QString str = QString("Detail Header %1").arg(props["Level"].first.toInt());
    painter.drawText(rect(), AlignVCenter | AlignLeft, str);
//		     qApp->translate("CanvasDetailHeader", "Detail Header"));
    CanvasBand::draw(painter);
}

QString CanvasDetailHeader::getXml()
{
    return "\t<DetailHeader" + CanvasBand::getXml() + "\t</DetailHeader>\n\n";
}


//CanvasDetail class

CanvasDetail::CanvasDetail(int x, int y, int width, int height, QCanvas * canvas):
	CanvasBand(x, y, width, height, canvas)
{
    pair<QString, QStringList> propValues;
    
    propValues.first = "50";
    propValues.second = "Detail height";
    propValues.second << "int";
    props["Height"] = propValues;
    propValues.second.clear();
    
    propValues.first = "0";
    propValues.second = "Detail level";
    propValues.second << "int";
    props["Level"] = propValues;
    propValues.second.clear();
}

void CanvasDetail::draw(QPainter &painter)
{
    QString str = QString("Detail %1").arg(props["Level"].first.toInt());
    painter.drawText(rect(), AlignVCenter | AlignLeft, str);
//		     qApp->translate("CanvasDetail", "Detail"));
    CanvasBand::draw(painter);
}

QString CanvasDetail::getXml()
{
    return "\t<Detail" + CanvasBand::getXml() + "\t</Detail>\n\n";
}


//CanvasDetailFooter class

CanvasDetailFooter::CanvasDetailFooter(int x, int y, int width, int height, QCanvas * canvas):
	CanvasBand(x, y, width, height, canvas)
{
    pair<QString, QStringList> propValues;
    
    propValues.first = "50";
    propValues.second = "Detail footer's height";
    propValues.second << "int";
    props["Height"] = propValues;
    propValues.second.clear();
    
    propValues.first = "0";
    propValues.second = "Detail footer's level";
    propValues.second << "int";
    props["Level"] = propValues;
    propValues.second.clear();
}

void CanvasDetailFooter::draw(QPainter &painter)
{
    QString str = QString("Detail footer %1").arg(props["Level"].first.toInt());
    painter.drawText(rect(), AlignVCenter | AlignLeft, str);
//		     qApp->translate("CanvasDetailFooter", "Detail Footer"));
    CanvasBand::draw(painter);
}

QString CanvasDetailFooter::getXml()
{
    return "\t<DetailFooter" + CanvasBand::getXml() + "\t</DetailFooter>\n\n";
}
