/******************************************************
 * File: DSAAlgorithm.java
 * created 16-Jul-00 3:27:14 PM by egiva
 */


package Main.algorithms;
import Main.*;
import java.util.*;


public class DSAAlgorithm extends AbstractAlgorithm
{
	/*int[] maxU;
	int[] maxV;*/
        //public int indeksas3;

	public void solve()
	{
		solve(true);
	}
	public void solve(boolean calculteUV)
	{
          
        indeksas = 0;
	if (indeksas2 == 0 ){
                mLog.logn("----------------------------------");
		mLog.logn("DSA BEGINS");
        }
		if(calculteUV)
		{
                    if (indeksas2 == 0 ){
                            mLog.logn("-- MATRIX U");
                            calculateMatrixU();
                            outputMatrix(getMatrixU());
                            mLog.logn("-- MATRIX V");
                            calculateMatrixV();
                            outputMatrix(getMatrixV());
                    } else
                    {
                            calculateMatrixU();
                            calculateMatrixV();
                    }
                }
		Vector maxU= new Vector(matrix.length);
		Vector maxV= new Vector(matrix.length);

		if (indeksas2 == 0 )
                    mLog.logn("-- MAX by column in U");

		for(int i= 0; i< matrixU.length;i++)
		{
			Vector temp= getMaxByCollumn(matrixU,i);
			maxU.add(temp);
                        if (indeksas2 == 0 )
                            mLog.log("{");
			for(int j= 0; j<temp.size(); j++) // +1 darasiau
			{
				ij ttemp= (ij)temp.get(j);
				if (indeksas2 == 0 )
                                    mLog.log("("+ttemp.i+","+ttemp.j+") ");
			}
			if (indeksas2 == 0 )
                            mLog.log("}");
		}

		if (indeksas2 == 0 )
                    mLog.logn();
                if (indeksas2 == 0 )
                    mLog.logn("-- MAX by row in V");
		for(int i= 0; i< matrixV.length;i++)
		{
			Vector temp= getMax(matrixV[i], i);
			maxV.add(temp);

			if (indeksas2 == 0 )
                            mLog.log("{");
			for(int j= 0; j<temp.size(); j++)    // +1 darasiau
			{
				ij ttemp= (ij)temp.get(j);
				if (indeksas2 == 0 )
                                    mLog.log("("+ttemp.i+","+ttemp.j+") ");
			}
			if (indeksas2 == 0 )
                            mLog.log("}");
		}
		if (indeksas2 == 0 )
                    mLog.logn();


		int rezultai[][]= getIntersection(maxU, maxV);
		if(rezultai == null || rezultai.length == 0)
		{
			indeksas3 = 0;
                        if (indeksas2 == 0 )
                            mLog.logn("--DSA ALGORITHM FAILED");
			setSolved(false);
		}
		else
		{
			indeksas3 = 5;
                        result= new double[matrixU.length][2];
			double value= 1f/(float)rezultai.length;
			if (indeksas2 == 0 )
                            mLog.logn("-- GENERATING OUTPUT");
                        
                            for(int i= 0; i < rezultai.length; i++)
                            {
                             if (indeksas2 == 0 )
                                 mLog.logn("INTERSECTION IJ=("+rezultai[i][1]+","+rezultai[i][0]+")");  
                            }
                            

                        result[rezultai[0][0]][0]= 1;
			result[rezultai[0][1]][1]= 1;

			setSolved(true);

			U= calculateU();
			V= calculateV();
                        indeksas3 = 5;
		}
		if (indeksas2 == 0 )
                {
                    mLog.logn("DSA ENDS");
                    mLog.logn("----------------------------------");
                }
		
                indeksas2 +=1;

	}
        

	private Vector getMax(double[] mas, int row)
	{
		if(mas == null || mas.length == 0)
			return null;
		Vector ret= new Vector(1);      
		double max= -1;
		for(int i= 0; i< mas.length; i++)
		{
			if(mas[i]>max)     
			{
				max= mas[i];
			}
		}

		//searching for alternative
		for(int i= 0; i< mas.length; i++)
		{
			if(mas[i]+0.0001 >= max)  
			{
				ret.add(new ij(row, i));
			}
		}

		return ret;
	}

	private Vector getMaxByCollumn(double[][] mas, int col)
	{

		if(mas == null || mas.length == 0)
			return null;
		Vector ret= new Vector(1);  
		double max= -1;
		for(int i= 0; i< mas.length; i++)
		{
			if(mas[i][col]>max)   
			{
				max= mas[i][col];
			}
		}

		//serching alternative
		for(int i= 0; i< mas.length; i++)
		{
			if(mas[i][col]+0.0001 >= max)
			{
				ret.add(new ij(i, col));
			}
		}
		return ret;
	}

	private int[][] getIntersection(Vector matrU, Vector matrV)
	{
		List list1= new ArrayList(1);
		List list2= new ArrayList(1);
		boolean nextIteration= false;
		for(int i= 0; i<matrU.size(); i++)
		{
			nextIteration= false;
			// can be more then one
			Vector insideU= (Vector)matrU.get(i);
			for(int ii= 0; ii< insideU.size(); ii++)
			{
				if(nextIteration)
				{
					break;
				}
				for(int j= 0; j<matrV.size(); j++)
				{
					if(nextIteration)
					{
						break;
					}
					//can be more than one
					Vector insideV= (Vector)matrV.get(j);
					for(int jj= 0; jj< insideV.size();jj++)
					{

						if(insideU.get(ii).equals(insideV.get(jj)))
						{
							list1.add(new Integer(i));
							list2.add(new Integer(j));
							nextIteration= true;
							break;
						}
					}
				}
			}
		}

		if(list1.size() == 0)
			return null;
		int[][] rez= new int[list1.size()][2];
		for(int i= 0; i< rez.length;i++)
		{
			rez[i][1]= ((Integer)list1.get(i)).intValue();
			rez[i][0]= ((Integer)list2.get(i)).intValue();;
		}
		return rez;
	}

	class ij
	{
		int i= -1;
		int j= -1;
		ij(int i, int j)
		{
			this.i= i;
			this.j= j;
		}

		public boolean equals(Object obj)
		{
			if(obj instanceof ij)
			{
				ij temp= (ij)obj;
				if(this.i == temp.i && this.j == temp.j )
					return true;
			}
			return false;
		}


	}
        

}
