/***************************************************************************
                           sidelib.cpp
                           -------------------
    copyright            : (C) 2004 by Jos van den Oever
    email                : jos@vandenoever.info
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 file contains a library of different sides that can be used for pasting
// on different sides of a cube.
// The sides are group by symmetry, first the sides with four equal
// orientations, then the sides with two equal orientations and then the sides
// with four different possible orientations.

#include "sidelib.h"
#include <q3picture.h>
#include <qpainter.h>
//Added by qt3to4:
#include <Q3PointArray>
#include <iostream>
using namespace std;

// the width of a side
int sidewidth = 256;

SideLib::SideLib()
	: c1max(3), c2max(5), c4max(6) {
	c1 = new Q3Picture*[c1max];	
	c2 = new Q3Picture*[c2max];	
	c4 = new Q3Picture*[c4max];	
	for (short i=0; i<c1max; ++i) {
		c1[i] = 0;
	}
	for (short i=0; i<c2max; ++i) {
		c2[i] = 0;
	}
	for (short i=0; i<c4max; ++i) {
		c4[i] = 0;
	}
}
SideLib::~SideLib() {
	for (short i=0; i<c1max; ++i) {
		if (c1[i]) delete c1[i];
	}
	for (short i=0; i<c2max; ++i) {
		if (c2[i]) delete c2[i];
	}
	for (short i=0; i<c4max; ++i) {
		if (c4[i]) delete c4[i];
	}
	delete [] c1;	
	delete [] c2;	
	delete [] c4;	
}
short
SideLib::amount(Symmetry s) const {
	switch (s) {
		case C1: return c1max;
		case C2: return c2max;
		case C4: return c4max;
		case none: return 0;
	}
	return 0;
}
/*const QPicture *
SideLib::getBlankPicture() {
	QPicture pict;
	QPainter p;
	QBrush b;

	p.begin(&pict);
	b.setStyle(Qt::SolidPattern);
	b.setColor(p.backgroundColor());
	p.fillRect(0, 0, sidewidth, sidewidth, b);
	b.setColor(p.pen().color());
	p.setBrush(b);
	p.end();
	return pict;
}
const QPicture *
SideLib::getNumberedPicture(int i) {
	QPicture pict;
	QPainter p;
	QBrush b;
	p.begin(&pict);
	b.setStyle(Qt::SolidPattern);
	b.setColor(p.backgroundColor());
	p.fillRect(0, 0, sidewidth, sidewidth, b);
	b.setColor(p.pen().color());
	p.setBrush(b);
	p.drawText(0, sidewidth/2, QString::number(i));
	p.end();
	return pict;
}*/

// four equal orientations
// ----- ----- ----- ----- ----- -----
// |   | |\ /| |@@@| |@@@| | | | |\|/|
// |   | | X | |@O@| |@@@| |-+-| |-X-|
// |   | |/ \| |@@@| |@@@| | | | |/|\|
// ----- ----- ----- ----- ----- -----
//   0     1     2     3     4     5
const Q3Picture *
SideLib::getC4Picture(ushort i) const {
	if (i > c4max) {
		cerr << "C4 maxxed out" << endl;
		throw 0;
	}
	if (c4[i]) {
		return c4[i];
	}
	Q3Picture *pict = new Q3Picture();
	c4[i] = pict;

	// start with an empty side
	QPainter p;
	QBrush b;
	p.begin(pict);
	b.setStyle(Qt::SolidPattern);
	b.setColor(p.backgroundColor());
	p.fillRect(0, 0, sidewidth, sidewidth, b);
	b.setColor(p.pen().color());
	p.setBrush(b);
	switch (i) {
	case 0:
		break;
	case 1:
		p.drawLine(0, 0, sidewidth, sidewidth);
		p.drawLine(0, sidewidth, sidewidth, 0);
		break;
	case 2:
		p.fillRect(0, 0, sidewidth, sidewidth, b);
		b.setColor(p.backgroundColor());
		p.setBrush(b);
		p.drawEllipse(sidewidth/3,sidewidth/3,sidewidth/3,sidewidth/3);
		break;
	case 3:
		p.fillRect(0, 0, sidewidth, sidewidth, b);
		break;
	case 4:
		p.drawLine(0, sidewidth/2, sidewidth, sidewidth/2);
		p.drawLine(sidewidth/2, 0, sidewidth/2, sidewidth);
		break;
	case 5:
		p.drawLine(0, sidewidth/2, sidewidth, sidewidth/2);
		p.drawLine(sidewidth/2, 0, sidewidth/2, sidewidth);
		p.drawLine(0, 0, sidewidth, sidewidth);
		p.drawLine(0, sidewidth, sidewidth, 0);
		break;
	}
	p.end();
//	pict->save("C4_"+QString::number(i)+".svg", "svg");
	return pict;
}

// two equal and two different orientations
// ----- ----- ----- ----- -----
// |  *| |  /| |  \| | @ | | | |
// |   | | / | |   | | @ | | | |
// |*  | |/  | |\  | | @ | | | |
// ----- ----- ----- ----- -----
//   0     1     2     3     4
const Q3Picture *
SideLib::getC2Picture(ushort i) const {
	if (i > c2max) {
		cerr << "C2 maxxed out" << endl;
		throw 0;
	}
	if (c2[i]) {
		return c2[i];
	}
	Q3Picture *pict = new Q3Picture();
	c2[i] = pict;
	// start with an empty side
	int px, py;
	QPainter p;
	QBrush b;
	Q3PointArray pa(3);
	p.begin(pict);
	b.setStyle(Qt::SolidPattern);
	b.setColor(p.backgroundColor());
	p.fillRect(0, 0, sidewidth, sidewidth, b);
	b.setColor(p.pen().color());
	p.setBrush(b);
	switch (i) {
	case 0:
		px = sidewidth/4 - sidewidth/20;
		py = sidewidth*3/4 - sidewidth/20;
		p.drawEllipse(px, py, sidewidth/10, sidewidth/10);
		px = sidewidth*3/4 - sidewidth/20;
		py = sidewidth/4 - sidewidth/20;
		p.drawEllipse(px, py, sidewidth/10, sidewidth/10);
		break;
	case 1:
		p.drawLine(0, sidewidth, sidewidth, 0);
		break;
	case 2:
		pa.setPoint(0, 0, sidewidth*2/3);
		pa.setPoint(1, 0, sidewidth);
		pa.setPoint(2, sidewidth/3, sidewidth);
		p.drawPolygon(pa);
		pa.setPoint(0, sidewidth*2/3, 0);
		pa.setPoint(1, sidewidth, 0);
		pa.setPoint(2, sidewidth, sidewidth/3);
		p.drawPolygon(pa);
		break;
	case 3:
		p.fillRect(sidewidth/3, 0, sidewidth/3, sidewidth, b);
		break;
	case 4:
		p.drawLine(sidewidth/2, 0, sidewidth/2, sidewidth);
		break;
	}
	p.end();
//	pict->save("C2_"+QString::number(i)+".svg", "svg");
	return pict;
}

// four different orientations
// ----- ----- -----
// |   | |@| | |  /|
// |   | |@| | | /@|
// |*  | |@| | |/@@|
// ----- ----- -----
//   0     1     2
const Q3Picture *
SideLib::getC1Picture(ushort i) const {
	if (i > c1max) {
		cerr << "C1 maxxed out:" << i << endl;
		throw 0;
	}
	if (c1[i]) {
		return c1[i];
	}
	Q3Picture *pict = new Q3Picture();
	c1[i] = pict;
	int px, py;
	QPainter p;
	QBrush b;

	// start with an empty side
	p.begin(pict);
	b.setStyle(Qt::SolidPattern);
	b.setColor(p.backgroundColor());
	p.fillRect(0, 0, sidewidth, sidewidth, b);
	b.setColor(p.pen().color());
	p.setBrush(b);
	switch (i) {
	case 0:
		px = sidewidth/4 - sidewidth/20;
		py = sidewidth*3/4 - sidewidth/20;
		p.drawEllipse(px, py, sidewidth/10, sidewidth/10);
		break;
	case 1:
		p.fillRect(0, 0, sidewidth/2, sidewidth, b);
		break;
	case 2:
		Q3PointArray pa(3);
		pa.setPoint(0, 0, sidewidth);
		pa.setPoint(1, sidewidth, sidewidth);
		pa.setPoint(2, sidewidth, 0);
		p.drawPolygon(pa);
		break;
	}
	p.end();
//	pict->save("C1_"+QString::number(i)+".svg", "svg");
	return pict;
}
// functions to draw the sides of a dice
// the diameter of a point on a dice
int pointdiameter = 25; 
int pointradius = pointdiameter/2; 

/* This function draws points number of dots on a QPicture and returns the
   QPicture. The dots are positioned on the QPicture as they are on the side
   of a dice. */
const Q3Picture
SideLib::diceside(short points) {
	int px, py;
	Q3Picture pict;
	QPainter p;
	QBrush b;

	p.begin(&pict);
	b.setStyle(Qt::SolidPattern);
	b.setColor(p.backgroundColor());
	p.fillRect(0, 0, sidewidth, sidewidth, b);
	b.setColor(p.pen().color());
	p.setBrush(b);
	// draw point in the center
	if (points == 1 || points == 3 || points == 5) {
		px = py = sidewidth/2 - pointradius;
		p.drawEllipse(px, py, pointdiameter, pointdiameter);
	}
	// draw points in two opposite corner (north-west & south-east)
	if (points > 1) {
		px = py = sidewidth/4 - pointradius;
		p.drawEllipse(px, py, pointdiameter, pointdiameter);
		px = py = sidewidth*3/4 - pointradius;
		p.drawEllipse(px, py, pointdiameter, pointdiameter);
	}
	// draw points in two opposite corner (north-east & south-west)
	if (points > 3) {
		px = sidewidth/4 - pointradius;
		py = sidewidth*3/4 - pointradius;
		p.drawEllipse(px, py, pointdiameter, pointdiameter);
		px = sidewidth*3/4 - pointradius;
		py = sidewidth/4 - pointradius;
		p.drawEllipse(px, py, pointdiameter, pointdiameter);
	}
	// draw points in the west and east
	if (points == 6) {
		px = sidewidth/2 - pointradius;
		py = sidewidth/4 - pointradius;
		p.drawEllipse(px, py, pointdiameter, pointdiameter);
		px = sidewidth/2 - pointradius;
		py = sidewidth*3/4 - pointradius;
		p.drawEllipse(px, py, pointdiameter, pointdiameter);
	}
	p.end();
//	pict.save("dice_"+QString::number(points)+".svg", "svg");
	return pict;
}
