void Docking::dockingSearchTest(double R, double beta1, double gamma1, double beta2, double gamma2,vector <pair<double, ScoreConfiguration> >& scores)
{
	RotationMatrix rotationMatrixGamma1, rotationMatrixBeta1;
	RotationMatrix rotationMatrixGamma2, rotationMatrixBeta2;

	rotationMatrixGamma1.calculateMatrix(receptor_.getOrder(), RotationAngle( 0, gamma1) );
	rotationMatrixBeta1.calculateMatrix(receptor_.getOrder(), RotationAngle( beta1, 0.0) );
	rotationMatrixGamma2.calculateMatrix(receptor_.getOrder(), RotationAngle( 0, gamma2) );
	rotationMatrixBeta2.calculateMatrix(receptor_.getOrder(), RotationAngle( beta2, 0.0));
	
	rotReceptor_ = new Protein[1];
	rotLigand_   = new Protein[alphaSize_];

	receptor_.rotateTo(rotReceptor_[0], rotationMatrixGamma1);
	rotReceptor_[0].rotate(rotationMatrixBeta1);
	
	ligand_.rotateTo  (rotLigand_[0], rotationMatrixGamma2);
	rotLigand_[0].rotate(rotationMatrixBeta2);

	Protein *transTmp; 
	if (R > 0)
	{
		transTmp = new Protein;
		char buffer[100];
		sprintf(buffer, "%s/%d/%.6lf.dat", translationPath_.c_str(), receptor_.getOrder(), R);
		TranslationMatrix translationmatrix(buffer);
		rotReceptor_[0].translateTo(*transTmp, translationmatrix);
	}else
	{
		transTmp = &rotReceptor_[0];
	}

	set <pair<double, ScoreConfiguration> > bestScores;
	scores.clear();
	double minScore = 10000000.0, maxScore = -10000000.0;
	for (int j = 1; j < alphaSize_; ++j)
	{
		rotLigand_[0].rotateTo(rotLigand_[j], ((2.0*PI)/alphaSize_) * j);
		double tmpScore = scoreIt(*transTmp, rotLigand_[j], penalty_);
		printf("%lf \n", tmpScore);

		bestScores.insert(make_pair(tmpScore,ScoreConfiguration(R, ((2.0*PI)/alphaSize_) * j, beta1, gamma1, beta2, gamma2)));

		minScore = min(minScore, tmpScore);
		maxScore = max(maxScore, tmpScore);
		while ((int)bestScores.size() > scoresSize_)
		{
			bestScores.erase(bestScores.begin());
		}
	}
	printf("For R:%lf min score is %lf; max score is %lf\n",R, minScore, maxScore);
	for (set <pair<double, ScoreConfiguration> >::iterator itr = bestScores.begin(); itr != bestScores.end(); ++itr)
	{
		scores.push_back(*itr);
	}

	if (R>0) delete transTmp;
}
void Docking::preDockingCalculateQRotations(void)
{
	if (rotatationsCalculated_ == false)
	{
		//printf("Kalkulisem Q rotacije\n");
		int raSize = 20*(1<<(tessellationOrder_*2));
		raSize ++; //dodao zbog nultog kuta
		//rotationAngles_ = new RotationAngle[raSize];
		rotationAngles_ = new RotationAngle[raSize]; //dodao zbog (0,0) kuta

		//printf("Generating Rotational Angles...\n");
		Rotational_Angles(tessellationOrder_, rotationAngles_);
		//printf("Generated Rotational Angles (%d of them)...\n", raSize);

		rotReceptor_ = new Protein[raSize];
		qRotLigand_   = new Protein[raSize];

		RotationMatrix rotationMatrixGamma, rotationMatrixBeta;

		//printf("Rotating receptor & ligand...\n");
		for (int i = 0; i < raSize; ++i)
		{

			/*if (  (abs(rotationAngles_[i].beta) < 0.00001) && (abs(rotationAngles_[i].gamma) < 0.00001) ){
				printf("NULA: %lf %lf \n", rotationAngles_[i].beta, rotationAngles_[i].gamma );			
			}*/			

			rotationMatrixGamma.calculateMatrix(receptor_.getOrder(), RotationAngle(0, rotationAngles_[i].gamma));
			rotationMatrixBeta.calculateMatrix(receptor_.getOrder(), RotationAngle(rotationAngles_[i].beta, 0.0));

			receptor_.rotateTo(rotReceptor_[i],            rotationMatrixGamma);
			rotReceptor_[i].rotate(rotationMatrixBeta);

			ligand_.rotateTo  (qRotLigand_[i], rotationMatrixGamma);
			qRotLigand_[i].rotate(rotationMatrixBeta);
			qRotLigand_[i].qTransition(penalty_);

		}
		//printf("Rotated successfully (total %d receptor, %d ligand)...\n", raSize, raSize*alphaSize_);

		rotatationsCalculated_ = true;
	}
}
void Docking::preDockingCalculateRotations(void)
{
	if (rotatationsCalculated_ == false)
	{
		//printf("Kalkulisem rotacije\n");
		int raSize = 20*(1<<(tessellationOrder_*2))+1;
		rotationAngles_ = new RotationAngle[raSize];

		//printf("Generating Rotational Angles...\n");
		Rotational_Angles(tessellationOrder_, rotationAngles_);
		//printf("Generated Rotational Angles (%d of them)...\n", raSize);

		rotReceptor_ = new Protein[raSize];
		rotLigand_   = new Protein[raSize*alphaSize_];

		RotationMatrix rotationMatrixGamma, rotationMatrixBeta;

		//printf("Rotating receptor & ligand...\n");
		for (int i = 0; i < raSize; ++i)
		{
			rotationMatrixGamma.calculateMatrix(receptor_.getOrder(), RotationAngle(0, rotationAngles_[i].gamma));
			rotationMatrixBeta.calculateMatrix(receptor_.getOrder(), RotationAngle(rotationAngles_[i].beta, 0.0));

			receptor_.rotateTo(rotReceptor_[i],            rotationMatrixGamma);
			rotReceptor_[i].rotate(rotationMatrixBeta);

			ligand_.rotateTo  (rotLigand_  [i*alphaSize_], rotationMatrixGamma);
			rotLigand_[i*alphaSize_].rotate(rotationMatrixBeta);

			// if (i%10 == 0) printf("...receptor %d...ligand %d...\n", i, i*alphaSize_);

			for (int j = 1; j < alphaSize_; ++j)
			{
				rotLigand_[i*alphaSize_].rotateTo(rotLigand_[i*alphaSize_+j], ((2.0*PI)/alphaSize_) * j);
			}
		}
		//printf("Rotated successfully (total %d receptor, %d ligand)...\n", raSize, raSize*alphaSize_);

		rotatationsCalculated_ = true;
	}
}
void Docking::setConfiguration(const ScoreConfiguration& scoreConfiguration, Protein &newReceptor, Protein &newLigand) const
{
	// rotate receptor
    RotationMatrix rotationMatrix;
    rotationMatrix.calculateMatrix(receptor_.getOrder(), RotationAngle(0.0, scoreConfiguration.gamma2));
	receptor_.rotateTo(newReceptor, rotationMatrix);
    rotationMatrix.calculateMatrix(receptor_.getOrder(), RotationAngle(scoreConfiguration.beta2, 0.0));
	newReceptor.rotate(rotationMatrix);

	// translate
	char buffer[100];
//	sprintf(buffer, "%s/%d/%.6lf.dat", "data/trans", receptor_.getOrder(), scoreConfiguration.R);
	sprintf(buffer, "%s/%d/%.6lf.dat", translationPath_.c_str(), receptor_.getOrder(), scoreConfiguration.R);
	TranslationMatrix translationmatrix(buffer);
	newReceptor.translate(translationmatrix);

    rotationMatrix.calculateMatrix(receptor_.getOrder(), RotationAngle(0.0, scoreConfiguration.gamma1));
	ligand_.rotateTo(newLigand, rotationMatrix);
    rotationMatrix.calculateMatrix(receptor_.getOrder(), RotationAngle(scoreConfiguration.beta1, 0.0));
	newLigand.rotate(rotationMatrix);
    rotationMatrix.calculateMatrix(receptor_.getOrder(), RotationAngle(0.0, scoreConfiguration.alpha));
	newLigand.rotate(rotationMatrix);
}
NS_IMETHODIMP
Touch::GetRotationAngle(float* aRotationAngle)
{
  *aRotationAngle = RotationAngle();
  return NS_OK;
}
void Docking::dockingQsearchTest(double R, double beta1, double gamma1, double beta2, double gamma2,vector <pair<double, ScoreConfiguration> >& scores)
{
	RotationMatrix rotationMatrixGamma1, rotationMatrixBeta1;
	RotationMatrix rotationMatrixGamma2, rotationMatrixBeta2;

	rotationMatrixGamma1.calculateMatrix(receptor_.getOrder(), RotationAngle( 0, gamma1) );
	rotationMatrixBeta1.calculateMatrix(receptor_.getOrder(), RotationAngle( beta1, 0.0) );
	rotationMatrixGamma2.calculateMatrix(receptor_.getOrder(), RotationAngle( 0, gamma2) );
	rotationMatrixBeta2.calculateMatrix(receptor_.getOrder(), RotationAngle( beta2, 0.0));
	
	rotReceptor_ = new Protein[1];
	qRotLigand_   = new Protein[1];

	receptor_.rotateTo(rotReceptor_[0], rotationMatrixGamma1);
	rotReceptor_[0].rotate(rotationMatrixBeta1);
	
	ligand_.rotateTo  (qRotLigand_[0], rotationMatrixGamma2);
	qRotLigand_[0].rotate(rotationMatrixBeta2);
	qRotLigand_[0].qTransition(penalty_); 

	Protein *transReceptor; 
	if (R > 0)
	{
		transReceptor = new Protein;
		char buffer[100];
		sprintf(buffer, "%s/%d/%.6lf.dat", translationPath_.c_str(), receptor_.getOrder(), R);
		TranslationMatrix translationmatrix(buffer);
		vector<int> translationIndexes;
		rotReceptor_[0].calculateTranslationIndexes( translationIndexes );
		rotReceptor_[0].translateTo(*transReceptor, translationmatrix, translationIndexes);	
	}else
	{
		transReceptor = &rotReceptor_[0];
	}

	set <pair<double, ScoreConfiguration> > bestScores;
	scores.clear();
	double minScore = 10000000.0, maxScore = -10000000.0;

	vector<double> qCoeffPlusPlus, qCoeffMinusMinus;
	int order = receptor_.getOrder();
	qCoeffPlusPlus.resize(order, 0.0);
	qCoeffMinusMinus.resize(order, 0.0);

	trigonometricCash();
	calculateCoeffMapping( );

	vector<double> qCoeffPlus;
	qCoeffPlus.resize((2* order - 1), 0.0); 
	vector<double> qCoeffMinus;
	qCoeffMinus.resize((2* order - 1), 0.0);
	//calculateQcoeffPlusPlus(qCoeffPlusPlus, qCoeffPlus ,*transReceptor, qRotLigand_[0] );
	//calculateQcoeffMinusMinus(qCoeffMinusMinus,qCoeffMinus, *transReceptor, qRotLigand_[0] );

	calculateQcoeffs(qCoeffPlusPlus, qCoeffPlus, qCoeffMinusMinus, qCoeffMinus,*transReceptor, qRotLigand_[0]);
	
	printf("Q Coeff plus plus : \n");
	for(int i = 0 ; i < qCoeffPlusPlus.size(); ++i) printf("%lf \n",qCoeffPlusPlus[i]);

	printf("Q Coeff minus minus : \n");
	for(int i = 0 ; i < qCoeffMinusMinus.size(); ++i) printf("%lf \n",qCoeffMinusMinus[i]);

	printf("Alfa function: \n");
	for (int j = 1; j < alphaSize_; ++j)
	{
		double tmpScore = qCoeffPlusPlus[0];
		int index_alfa = j*order;
		for (int m = 1; m <= (order-1); ++m)
		{
			double alfa2angle = j*((2.0*PI)/alphaSize_);
			//tmpScore += (qCoeffPlusPlus[m] * cos(m*alfa2angle) ) + (qCoeffMinusMinus[m] * sin(m*alfa2angle) );
			tmpScore += (qCoeffPlusPlus[m] * cosValue_->at(index_alfa+m) ) + (qCoeffMinusMinus[m] * sinValue_->at(index_alfa+m) );
		}
		printf("%lf \n", tmpScore);

		bestScores.insert(make_pair(tmpScore,ScoreConfiguration(R, ((2.0*PI)/alphaSize_) * j, beta1, gamma1, beta2, gamma2)));

		minScore = min(minScore, tmpScore);
		maxScore = max(maxScore, tmpScore);
		while ((int)bestScores.size() > scoresSize_)
		{
			bestScores.erase(bestScores.begin());
		}
	}

	printf("For R:%lf min score is %lf; max score is %lf\n",R, minScore, maxScore);
	for (set <pair<double, ScoreConfiguration> >::iterator itr = bestScores.begin(); itr != bestScores.end(); ++itr)
	{
		scores.push_back(*itr);
	}

	if (R>0) delete transReceptor;
}