#include <iostream>
#include <list>
#include <math.h>

extern void find_xy(int p, int *x, int *y);
using namespace std ;

class decomposition     {
public:

         int array[4];
         decomposition(int a1, int a2, int a3, int a4);
         decomposition();

};
int four_squar(int num, decomposition **d_ptr, int ps);
void reduce_decomp( decomposition *d_ptr, int ps, int q);

decomposition::decomposition(int a1, int a2, int a3, int a4)    {

                 array[0]=a1;
                 array[1]=a2;
                 array[2]=a3;
                 array[3]=a4;

}
decomposition::decomposition()  {
                 int i;
                 for (i=0; i < 4; i++)   array[i] = 0;
}




int four_squar(int num, decomposition **d_ptr)
{
list <decomposition> l1;
list <decomposition>::iterator l1_Iter;
int i,j,x,y, up_lim;


up_lim = (int)sqrt((double)num) +1;


for (i=-up_lim; i < up_lim; i++)
                 for (j=-up_lim; j < up_lim; j++)
                         for (x=-up_lim; x < up_lim; x++)
                                 for (y=-up_lim; y < up_lim; y++)      {
									 if ((i*i + j*j + x*x +y*y) == 
										 num) { 
									
                                                 l1.push_back(decomposition(i,j,x,y));

								 } }

// Display  the list
/*
cout << "\ndecompos:\n:";
if (l1. size() == 0)            {
         cout << "none";
         return(0);
}

for (l1_Iter =  l1.begin(); l1_Iter != l1.end(); ++l1_Iter)     {
                 cout << "\n[" ;
                 for (i=0;i <4; i++)
                         cout  << l1_Iter->array[i] << ",";
                 cout << "]";
}

*/



*d_ptr = new decomposition[l1.size()];

i =0;
for (l1_Iter =  l1.begin(); l1_Iter != l1.end(); ++l1_Iter)     {
				
                 (*d_ptr)[i++]= *l1_Iter;
}

  return (l1.size());
}

void reduce_decomp( decomposition *d_ptr, int size, int q)
{

         int l, j;


         for (l=0; l < size; l++)        {
                 for (j=0;j <4; j++)
					  d_ptr[l].array[j]=d_ptr[l].array[j]%q;

		 }



}

void distinguished (decomposition *d_ptr, decomposition *nd, int size, int p) {
	// assume p = 1 mod 4
	int l;
	int k=0;
	int *indices = new int[size];
	
	std::cout << "\n Entering Distinguished!";

		for (l=0; l < size; l++)        {
			if ( d_ptr[l].array[0]%2==1) {
						 indices[k]=l;
						 std::cout << "\n k = " << k << " and l = " << l;
						  k++;
			}
			
						 
		 }

		for(k=0;k<p+1;k++) {
	//		std::cout << "\n indices[" << k << "] is " << indices[k];
	//		std::cout << "\n d_ptr[indices[" << k << "]].array[0] is " << d_ptr[indices[k]].array[0];
	//		std::cout << "\n d_ptr[indices[" << k << "]].array[1] is " << d_ptr[indices[k]].array[1];
	//		std::cout << "\n d_ptr[indices[" << k << "]].array[2] is " << d_ptr[indices[k]].array[2];
	//		std::cout << "\n d_ptr[indices[" << k << "]].array[3] is " << d_ptr[indices[k]].array[3];
			nd[k].array[0] = d_ptr[indices[k]].array[0];
			nd[k].array[1] = d_ptr[indices[k]].array[1];
			nd[k].array[2] = d_ptr[indices[k]].array[2];
			nd[k].array[3] = d_ptr[indices[k]].array[3];

		}

		

delete[] indices;



}


