#include <cairo.h>

#include <tqpainter.h>
#include <tqapplication.h>
#include <tqstyle.h>

#include "tqtcairopainter.h"

// TQt3 test image only
#include <tqpixmap.h>

void drawColorWheel(TQPainter *p, double scale)
{
	TQFont f( "times", 18, TQFont::Bold );
	p->setFont( f );
	p->setPen(TQt::black);
	p->setWindow( 0, 0, 500*scale, 500*scale );                 // defines coordinate system
	
	for ( int i=0; i<36; i++ ) {                    // draws 36 rotated rectangles
		TQWMatrix matrix;
		matrix.translate( 250.0F*scale, 250.0F*scale );     // move to center
		matrix.shear( 0.0F*scale, 0.3F*scale );             // twist it
		matrix.rotate( (float)i*10 );           // rotate 0,10,20,.. degrees
		p->setWorldMatrix( matrix );            // use this world matrix
		
		TQColor c;
		c.setHsv( i*10, 255, 255 );             // rainbow effect
		p->setBrush( c );                       // solid fill with color c
		p->drawRect( 70*scale, -10*scale, 80*scale, 10*scale );         // draw the rectangle
		
		TQString n;
		n.sprintf( "H=%d", i*10 );
		p->drawText( (80+70+5)*scale, 0, n );           // draw the hue number
	}
}

void runTests(TQPaintDevice* pd) {
	TQPainter p(pd);

	// Background
	{
		p.setPen( TQt::NoPen );
		TQBrush brush(TQColor(0,0,0), TQBrush::SolidPattern);
		p.setBrush(brush);
		p.drawRect(0,0,1000,1000);
	}

	// Rectangle tests
	{
		p.setPen(TQPen(TQt::red, 1));
		p.drawRect(5, 5, 50, 50);
		TQBrush brush( TQt::yellow, TQBrush::DiagCrossPattern ); // yellow pattern
		p.setBrush( brush );                                     // set the yellow brush
		p.setPen( TQt::NoPen );                                  // do not draw outline
		p.drawRect( 0,0, 25,25 );                                // draw filled rectangle
		p.drawRect( 452,400, 25,25 );                            // draw filled rectangle
		TQBrush brush2( TQt::green, TQBrush::SolidPattern );     // green pattern
		p.setBrush( brush2 );                                    // set the green brush
		p.setPen( TQt::NoPen );                                  // do not draw outline
		p.drawRect( 40,30, 200,100 );                            // draw filled rectangle
		p.setBrush( TQt::NoBrush );                              // do not fill
		p.setPen( TQt::blue );                                   // set blue pen, 0 pixel width
		p.drawRect( 10,10, 30,20 );                              // draw rectangle outline
		TQBrush brush3( TQColor(255,128,0), TQBrush::SolidPattern );     // green pattern
		p.setBrush( brush3 );                                    // set the yellow brush
		p.setPen( TQColor(255,0,255) );                          // draw outline
		p.drawRect( 50,40, 180,80 );                             // draw filled rectangle
	}

	// Line tests
	{
		p.setPen( TQt::blue );                                   // set blue pen, 0 pixel width
		p.drawLine(140,140, 160,160);
		p.setPen( TQt::blue );                                   // set blue pen, 0 pixel width
		p.drawLine(470,140, 480,160);
		p.setPen( TQt::blue );                                   // set blue pen, 0 pixel width
		p.drawLine(470,170, 490,170);
		p.setPen( TQPen(TQt::blue, 1) );                         // set blue pen, 1 pixel width
		p.drawLine(470,180, 490,180);
		p.setPen( TQPen(TQt::blue, 2) );                         // set blue pen, 2 pixel width
		p.drawLine(470,190, 490,190);
		p.setPen( TQPen(TQt::blue, 3) );                         // set blue pen, 3 pixel width
		p.drawLine(470,200, 490,200);
		p.setPen( TQPen(TQt::blue, 4) );                         // set blue pen, 4 pixel width
		p.drawLine(470,210, 490,210);
		p.setPen( TQPen(TQt::blue, 5) );                         // set blue pen, 5 pixel width
		p.drawLine(470,220, 490,220);
		p.setPen( TQPen(TQt::blue, 6) );                         // set blue pen, 6 pixel width
		p.drawLine(470,230, 490,230);
	}

	// Point tests
	{
		p.setPen( TQt::green );                                  // set green pen, 0 pixel width
		p.drawPoint(135,135);
	}

	// Polyline tests
	{
		TQPointArray a;
		int x1 = 250;
		int y1 = 10;

		a.setPoints( 11, x1+0, y1+85, x1+75, y1+75, x1+100, y1+10, x1+125, y1+75, x1+200, y1+85, x1+150, y1+125, x1+160, y1+190, x1+100, y1+150, x1+40, y1+190, x1+50, y1+125, x1+0, y1+85 );
		p.setPen(TQt::red);
		p.drawPolyline(a);
	}

	// Polyfill tests
	{
		TQPointArray a;
		int x1 = 250;
		int y1 = 200;

		a.setPoints( 11, x1+0, y1+85, x1+75, y1+75, x1+100, y1+10, x1+125, y1+75, x1+200, y1+85, x1+150, y1+125, x1+160, y1+190, x1+100, y1+150, x1+40, y1+190, x1+50, y1+125, x1+0, y1+85 );
		p.setPen(TQt::blue);
		p.setBrush(TQt::green);
		p.drawPolygon(a);
	}

	// Rounded rectangle tests
	{
		p.setBrush(TQt::green);
		p.setPen(TQPen(TQt::red, 1));
		p.drawRoundRect(10, 150, 50, 50);
		p.setBrush(TQBrush());
		p.setPen(TQPen(TQt::blue, 1));
		p.drawRoundRect(80, 150, 50, 50);
		p.setBrush(TQt::green);
		p.setPen(TQPen());
		p.drawRoundRect(150, 150, 50, 50);
	}

	// Ellipse tests
	{
		p.setBrush(TQt::green);
		p.setPen(TQPen(TQt::red, 1));
		p.drawEllipse(10, 220, 50, 50);
		p.setBrush(TQBrush());
		p.setPen(TQPen(TQt::blue, 1));
		p.drawEllipse(80, 220, 50, 50);
		p.setBrush(TQt::green);
		p.setPen(TQPen());
		p.drawEllipse(150, 220, 50, 50);
	}

	// Arc tests
	{
		p.setBrush(TQBrush());
		p.setPen(TQPen(TQt::yellow, 1));
		p.drawArc(10,10, 70,100, 100*16, 160*16); // draws a "(" arc
	}

	// Pie tests
	{
		p.setBrush(TQBrush());
		p.setPen(TQPen(TQt::red, 1));
		p.drawPie(250, 400, 200, 100, 45*16, 90*16);
		p.setBrush(TQt::green);
		p.setPen(TQPen(TQt::blue, 1));
		p.drawPie(250, 450, 200, 100, 45*16, 90*16);
	}

	// Chord tests
	{
		p.setBrush(TQBrush());
		p.setPen(TQPen(TQt::red, 1));
		p.drawChord(100, 400, 200, 100, 45*16, 90*16);
		p.setBrush(TQt::green);
		p.setPen(TQPen(TQt::blue, 1));
		p.drawChord(100, 450, 200, 100, 45*16, 90*16);
	}

	// Line segment tests
	{
		TQPointArray a;
		int x1 = 10;
		int y1 = 400;

		a.setPoints( 4, x1+0, y1+85, x1+75, y1+75, x1+0, y1+95, x1+75, y1+85 );
		p.setPen(TQColor(255,128,0));
		p.drawLineSegments(a);
	}

	// Bezier curve tests
	{
		TQPointArray a;
		int x1 = 100;
		int y1 = 400;

		a.setPoints( 4, x1+0, y1+85, x1+75, y1+75, x1+0, y1+95, x1+75, y1+85 );
		p.setPen(TQColor(0,128,255));
		p.drawCubicBezier(a);
	}

#if 1
	// Pixmap tests
	{
		TQPixmap pixmap("open.png");
		p.drawPixmap(200, 10, pixmap, 0, 0, -1, -1);
	}

	// Image tests
	{
		TQImage image("open.png");
		p.drawImage(350, 10, image, 0, 0, -1, -1);
	}
#endif

#if 0
	// Font tests
	{
		p.setPen(TQColor(0,128,255));

		static const char *fonts[] = { "Helvetica", "Courier", "Times", 0 };
		static int   sizes[] = { 10, 12, 18, 24, 36, 0 };
		int f = 0;
		int y = 0;
		while ( fonts[f] ) {
			int s = 0;
			while ( sizes[s] ) {
				TQFont font( fonts[f], sizes[s] );
				p.setFont( font );
				TQFontMetrics fm = p.fontMetrics();
				y += fm.ascent();
				p.drawText( 10, y, "TQt3 renders via Cairo!" );
				y += fm.descent();
				s++;
				if (y > 500) {
					break;
				}
			}
			f++;
			if (y > 500) {
				break;
			}
		}

		//p.setPen(TQColor(255,128,0));
		//p.drawText( TQRect(250, 250, 250, 150), TQt::BreakAnywhere, TQString("TQt3 renders via Cairo!") );

		//p.setPen(TQColor(255,0,128));
		//p.drawText( TQRect(0, 250, 250, 150), TQt::BreakAnywhere | TQt::AlignCenter, TQString("TQt3 renders via Cairo!") );
		//p.drawText( TQRect(0, 250, 250, 150), TQt::BreakAnywhere | TQt::AlignHCenter | TQt::AlignBottom, TQString("TQt3 renders via Cairo!") );
	}
#endif

	// Clipping tests
	{
		p.setBrush(TQBrush(TQt::green));
		p.setPen(TQPen(TQt::blue, 1));
		TQRect boundary(400, 10, 100, 100);
		TQRegion rectRegion(425,35,50,50);
		p.setClipRegion(rectRegion);
		p.fillRect(boundary, TQBrush(TQt::green));
		p.setClipping(false);
	}

	// Raster operation tests
	{
		p.setRasterOp(TQPainter::XorROP);
		p.setBrush(TQBrush(TQt::white));
		p.setPen(TQPen());
		p.drawRect(325, 275, 50, 50);
		p.setRasterOp(TQPainter::CopyROP);
	}

	//drawColorWheel(&p, 0.5);
	//drawColorWheel(&p, 1.0);

	TQColorGroup cg;
	cg.setColor(TQColorGroup::Background, TQColor(128,128,128));
	cg.setColor(TQColorGroup::Foreground, TQColor(0,0,0));
	tqApp->style().drawPrimitive(TQStyle::PE_ExclusiveIndicator, &p, TQRect(400, 400, 16, 16), cg, TQStyle::Style_Down);

	// Tab bar tab tests
	{
		int currentPage;
		int numPages=3;
		int tabIndex=2;

		int x = 0;
		int y = 300;
		int width = 50;
		int height = 20;

		for (currentPage=0;currentPage<numPages;currentPage++) {
			TQRect boundingRect(0, 0, width, height);

			TQStringList objectTypes;
			objectTypes.append(TQTABBAR_OBJECT_NAME_STRING);
			TQPalette objectPalette = tqApp->palette(objectTypes);
	
			TQStyleControlElementData ceData;
			TQStyle::ControlElementFlags elementFlags;
			ceData.widgetObjectTypes = objectTypes;
			ceData.rect = boundingRect;
	
			TQTab tqt3Tab;
			tqt3Tab.setIdentifier(currentPage);
			TQStyleOption tabOpt(&tqt3Tab, (TQTab*)NULL);
	
			elementFlags = elementFlags | TQStyle::CEF_HasParentWidget;
			ceData.parentWidgetData.widgetObjectTypes.append(TQTABBAR_OBJECT_NAME_STRING);
	
			int tab_overlap = tqApp->style().pixelMetric(TQStyle::PM_TabBarTabOverlap);
			x = x + width + tab_overlap;
	
			boundingRect = TQRect(x, y, width+(tab_overlap*2), height);
	
			ceData.tabBarData.shape = TQTabBar::RoundedAbove;
			ceData.tabBarData.tabCount = numPages;
			ceData.tabBarData.identIndexMap[tqt3Tab.identifier()] = currentPage;

			TQColorGroup cg = tqApp->palette().active();
	
			// Draw tab
			tqApp->style().drawControl(TQStyle::CE_TabBarTab, &p, ceData, elementFlags, boundingRect, cg, ((tabIndex==currentPage)?TQStyle::Style_Selected:TQStyle::Style_Default), tabOpt);
		}
	}
	{
		int currentPage;
		int numPages=3;
		int tabIndex=2;

		int x = (50*4);
		int y = 325;
		int width = 50;
		int height = 20;

		for (currentPage=(numPages-1);currentPage>=0;currentPage--) {
			TQRect boundingRect(0, 0, width, height);

			TQStringList objectTypes;
			objectTypes.append(TQTABBAR_OBJECT_NAME_STRING);
			TQPalette objectPalette = tqApp->palette(objectTypes);
	
			TQStyleControlElementData ceData;
			TQStyle::ControlElementFlags elementFlags;
			ceData.widgetObjectTypes = objectTypes;
			ceData.rect = boundingRect;
	
			TQTab tqt3Tab;
			tqt3Tab.setIdentifier(currentPage);
			TQStyleOption tabOpt(&tqt3Tab, (TQTab*)NULL);
	
			elementFlags = elementFlags | TQStyle::CEF_HasParentWidget;
			ceData.parentWidgetData.widgetObjectTypes.append(TQTABBAR_OBJECT_NAME_STRING);
	
			int tab_overlap = tqApp->style().pixelMetric(TQStyle::PM_TabBarTabOverlap);
			x = x - width - tab_overlap;
	
			boundingRect = TQRect(x, y, width+(tab_overlap*2), height);
	
			ceData.tabBarData.shape = TQTabBar::RoundedAbove;
			ceData.tabBarData.tabCount = numPages;
			ceData.tabBarData.identIndexMap[tqt3Tab.identifier()] = currentPage;

			TQColorGroup cg = tqApp->palette().active();
	
			// Draw tab
			tqApp->style().drawControl(TQStyle::CE_TabBarTab, &p, ceData, elementFlags, boundingRect, cg, ((tabIndex==currentPage)?TQStyle::Style_Selected:TQStyle::Style_Default), tabOpt);
		}
	}

	p.end();
}

int
main (int argc, char *argv[])
{
        cairo_surface_t *surface;
        cairo_t *cr;

        surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 500, 500);
//         cr = cairo_create (surface);

// 	/* Examples are in 1.0 x 1.0 coordinate space */
// 	cairo_scale (cr, 120, 120);
// 
// 	/* Drawing code goes here */
// 	cairo_set_line_width (cr, 0.1);
// 	cairo_set_source_rgb (cr, 0, 0, 0);
// 	cairo_rectangle (cr, 0.25, 0.25, 0.5, 0.5);
// 	cairo_stroke (cr);

	// Initialize TQApplication required data structures
	new TQApplication(argc, argv, TRUE);

	TQt3CairoPaintDevice pd(surface);
	runTests(&pd);

	/* Write output and clean up */
        cairo_surface_write_to_png (surface, "stroke.png");
//         cairo_destroy (cr);
        cairo_surface_destroy (surface);

	// Render a TQt3 native test image
	TQPixmap pm(500, 500);
	pm.fill(TQt::black);
	runTests(&pm);
	pm.save("tqt3.png", "PNG");

        return 0;
}

