/***************************************************************************
                           testqg.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.                                   *
 *                                                                         *
 ***************************************************************************/
#include "questiongenerator.h"
#include <iostream>
using std::cout;
using std::endl;
using std::flush;

bool
advance(short *t, Symmetry *s) {
	bool moved = false;
	short i=5;
	do {
		if (i == 0) {
			if (s[i] == C1) {
				return false;
			} else if (s[i] == C2) {
				for (short j=0; j<6; ++j) {
					s[j] = C1;
					t[j] = 0;
				}
				return true;
			} else {
				if (t[0] == 0) {
					for (short j=0; j<6; ++j) {
						s[j] = C4;
						t[j] = 1;
					}
					return true;
				} else {
					for (short j=0; j<6; ++j) {
						s[j] = C2;
						t[j] = 0;
					}
					return true;
				}
			}
		}
		if (s[i] == s[i-1]) {
			if (t[i] == t[i-1]) {
				if (t[i] == 0 && s[i] == C4) {
					for (short j=i; j<6; ++j) {
						s[j] = C4;
						t[j] = 1;
					}
					return true;
				}
				short np = 0;
				for (short j=i-1; j>=0 && s[j] == s[i-1]
					&& t[j] == t[i-1]; --j) {
					++np;
				}
				short j=i;
				short p=1;
				do {
					for (;j<6 && j<i+p*np; ++j) {
						s[j] = s[i-1];
						t[j] = t[i-1]+p;
					}
					p++;
				} while (j < 6);
				return true;
			} else {
				if (s[i] == C4) {
					for (short j=i; j<6; ++j) {
						s[j] = C2;
						t[j] = 0;
					}
					return true;
				} else if (s[i] == C2) {
					for (short j=i; j<6; ++j) {
						s[j] = C1;
						t[j] = 0;
					}
					return true;
				} else {
					i--;
				}
			}
		} else if (s[i] == C2) {
			for (short j=i; j<6; ++j) {
				s[j] = C1;
				t[j] = 0;
			}
			return true;
		} else {
			i--;
		}
	} while(!moved);
	return moved;
}

void
makeCapList() {
	short types[6];
	Symmetry sym[6];
	for (short i=0; i<6; ++i) {
		types[i] = 0;
		sym[i] = C4;
	}
	Question q;
	QuestionGenerator qg;
	qg.setStyleRestrictions(6,6,7);
	do {
		short nb, n1, n2, n4;
		nb = n1 = n2 = n4 = 0;
		for (short i=0; i<6; ++i) {
			q.shownTypes[i] = types[i];
			q.shownSyms[i] = sym[i];
			if (sym[i] == C1) n1++;
			if (sym[i] == C2) n2++;
			if (sym[i] == C4 && types[i] == 0) nb++;
			if (sym[i] == C4 && types[i] > 0) n4++;
		}
		// filter out what we know
//		if (!( nb+n4>4 || nb+n4==4 || nb+n4==3 || (n1>1&&n1<6)
//			|| n2==2 || n2==3)) { 
			for (short i=0; i<6; ++i) {
				cout << types[i] << ' ';
				cout << sym[i] << ' ';
			}
			cout <<" 0:"<<nb<<" 4:"<<n4<<" 04:"<<nb+n4<<" 2:"<<n2<<" 1:"<<n1<<"  "<<flush;
			for (short i=0; i<6; ++i) {
				short j;
				if (types[i] == 0) j++;
				if (sym[i] == C1) j++;
			}
			qg.makeQuestion(q);
			cout << q.valid;
			cout << endl;
//		}
	} while(advance(types, sym));
}

int main(int argc, char **argv) {
	srand(time(NULL));
	if (argc < 13) {
		makeCapList();
		return 0;
	}
	Question q;
	for (short i=0; i<6; ++i) {
		q.shownTypes[i] = atoi(argv[1+2*i]);
		q.shownSyms[i] = Symmetry(atoi(argv[2+2*i]));
	}
	for (short i=0; i<6; ++i) {
		cout << q.shownTypes[i] << ' ';
		cout << q.shownSyms[i] << ' ';
	}
	cout << endl;
	
	QuestionGenerator qg;
	qg.setStyleRestrictions(6,6,7);
	qg.makeQuestion(q);
	if (q.valid) {
		for (short i=0; i<6; ++i) {
			cout << q.cube.type[i] << ' ';
			cout << q.cube.sym[i] << ' ';
		}
		cout << endl;
	}





/*	if (argc > 1) {
		srand(atoi(argv[1]));
	} else {
		srand(time(NULL));
	}
	QuestionGenerator qg;
	qg.setStyleRestrictions(6,6,7);
	for (short sm1=0; sm1<=6; sm1++) {
	for (short sm2=0; sm2<=6; sm2++) {
	for (short sm4=0; sm4<=6; sm4++) {
	for (short nb=0; nb<=3; nb++) {
	short left = 6-nb;
	for (short nc1=-1; nc1<=left && (sm1>0||nc1<0); nc1++) {
	if (nc1 != -1) left -= nc1;
	for (short nc2=-1; nc2<=left && (sm2>0||nc2<0); nc2++) {
	if (nc2 != -1) left -= nc2;
	for (short nc4=-1; nc4<=left && (sm4>0||nc4<0); nc4++) {
		qg.setBlanks(nb);
		qg.setNumSyms(nc1, nc2, nc4);
		qg.setDiffSyms(sm1,sm2,sm4);
		cout << sm1 << '\t'<< sm2<<"\t"<<sm4<<"\t";
		cout << nb << '\t';
		cout << nc1 << '\t'<< nc2<<"\t"<<nc4<<"\t"<<std::flush;
		Question q = qg.makeQuestion();
		cout <<q.valid << endl;
	} } } } } } }*/
/*	qg.setStyleRestrictions(1,1,1);
	qg.setNumSyms(-1,5,-1);
	for (short i=0; i<105; i++) {
		Question q = qg.makeQuestion();
		cout << i << "\t" << q.valid << endl;
	}*/
//	cout << "ndC1 "<<qg.ndC1 <<" ndC2 "<<qg.ndC2<<" ndC4 "<<qg.ndC4<<endl;
//	cout << "ndC1 "<<qg.nC1 <<" ndC2 "<<qg.nC2<<" ndC4 "<<qg.nC4<<endl;
	return 0;
}
