package lt.ktu.gmj.tasks;

import defaultPackage.Counter_Portfel;
import java.util.Vector;


import lt.ktu.gmj.Domain;
import lt.ktu.gmj.Point;
import lt.ktu.gmj.Task;
import lt.ktu.mockus.srgm.StockContainer;


public class PortfelTask implements Task {
	private Domain domain = new Domain();

	int Iterations, InitialPoint;
        double x[];

	double Resours;

	int InType;

	String mMethod;

	Counter_Portfel Counter;

	Vector wItVector, wFVector;

	boolean SuspendStatus = false, StopStatus = false, FrameCreated = false;

	int Risk = 3, it = 0, Length = 0;

	double SumMax = -1000000.0;
        /*double Ri[][];
        double Ri_[];*/
        double p[];
        
        double Rp_ = 0;
        StockContainer stocksPrices[];
        int Iter = 0;
        double result[];
        
        
        double bankrupt[];
        double aIndex[];
        
        //Risk
        
        double naud_f[][] = { 
                        { 1.0, 1.0, 1.0,         1.0, 1.0, 1.0,      1.0, 1.0, 1.0,  1.0 },
			{ 0.5, 0.25, 0.125,      0.075, 0.035, 0.03, 0.025, 0.012, 0.007, 0.005  },
			{ 2.5, 2.4, 2.3,         2.2,2.1,2.0,         1.9, 1.8, 1.7 , 1.6 }, 
                        { 2.5, 2.4, 2.3,         2.2,2.1,2.0,         1.9, 1.8, 1.7, 1.7 }
                        };
        
	public PortfelTask() {
            System.out.println( "Portefel task me constructor " );
	}
        public void setParameters( int Iterations[], int InType, double Resours,
			StockContainer stocksPrices[],  double  result[],  String mMethod, double bankrupt [], double profitability[] ) {

            System.out.println( "Portfel task set parameters" );
		this.Iterations = Iterations[0];
		this.InitialPoint = Iterations[1];
		this.InType = InType;
		this.Resours = Resours;
                this.stocksPrices = stocksPrices;
		this.mMethod = mMethod;
                Length = stocksPrices.length;
                Iter = stocksPrices[0].getIterNr();
                this.result = result;
                this.bankrupt = bankrupt;
                this.aIndex = profitability;
	}
        
        public double UX( double x  ) {
            if ( InType  > 3 || InType < 0 ) return 1;
            if ( x >= 0 && x < 0.1 ) return naud_f[InType][0];
            if ( x >= 0.1 && x < 0.2 ) return naud_f[InType][1];
            if ( x >= 0.2 && x < 0.3 ) return naud_f[InType][2];
            
            if ( x >= 0.3 && x < 0.4 ) return naud_f[InType][3];
            if ( x >= 0.4 && x < 0.5 ) return naud_f[InType][4];
            if ( x >= 0.5 && x < 0.6 ) return naud_f[InType][5];
            
            if ( x >= 0.6 && x < 0.7 ) return naud_f[InType][6];
            if ( x >= 0.7 && x < 0.8 ) return naud_f[InType][7];
            if ( x >= 0.8 && x < 0.9 ) return naud_f[InType][8];
            
            if ( x >= 0.9 && x <= 1.0 ) return naud_f[InType][9];
            
            System.out.println( "Nepasirinko if, == 1 " );
            return 1;
        }
        
        /*void getP() {
           // System.out.println( "getP Sharptask Leghtn = " + Length + " Iter = " + Iter );
            //Ri = new double[Length][Iter];
            //Ri_ =  new double[Length];
            aIndex = new double[Length];
            //int a = 0, i = 0;
            double p = 0;
            for( int i = 0; i < Length; i++ ) {
                for (  int t = 0; t < Iter; t++ ) {
                    if ( t == 0 ) Ri[i][t] = 0;
                    else {
                        p = ( stocksPrices[i].get(t) - stocksPrices[i].get(t-1) ) / stocksPrices[i].get(t-1);
                        //Ri[i][t] = p * Resours;
                        //System.out.println(" Ri[" + i + "][" + t + "] = " + p + " * " + Resours + " = " + Ri[i][t] );
                    }
                    //Ri_[i] += Ri[i][t];
                }
                
            }
            //System.out.println( "Ri_ dlina = " + Ri_.length );
            for( int temp = 0; temp < Length ; temp++ ){
                Ri_[temp] = Ri_[temp] / Iter;
                //System.out.println( "Ri_[ " + temp + " ] = " + Ri_[temp]  );
            }
            
            
        }*/

	public Domain domain() {
		return domain;
	}

	public void CounterPoint(Thread Counter) {
		this.Counter = (Counter_Portfel)Counter;
	}

	/*- Function fi --------------------------------------------*/

	public double f(Point pt) {
		//getP();
                x = new double[Length];
		double viso = 0;
		// System.out.println("Length "+pt.x.length);
		for (int i = 0; i < Length; i++)
			viso += pt.x[i];
		if (viso == 0)
			return 0; // data can't be normalize
		if (viso > 1)
			for (int i = 0; i < Length; i++)
				x[i] = pt.x[i] / viso; // normalize
		else
			for (int i = 0; i < Length; i++)
				x[i] = pt.x[i];

		++it;
		/*
                this.getP();
                */
                double Sum = 0.0;
                int counter = (int)Math.pow( 2, Length );
                
                for ( int i = 0; i < counter; i++ ) {
                    double y = 0;
                    double prob = 1;
                    //int a = 1;
                    int u = 0;
                    //System.out.println("************************************************");
                    
                    for ( int j = 0; j < x.length; j++ ) {
                        int temp = (int)Math.pow(2, j);
                        if ( ( i & temp ) > 0 )  { 
                            //y+= x[j] * Resours * aIndex[j];
                            y =  x[j] * Resours * aIndex[j];
                            u += UX( x[j] ) * y;
                            //System.out.println( "y " + i + " " + j + " = " + x[j] + " * " + Resours + " * " + a );
                            //System. out.println( " prob = " + i + " " + j + " = " + prob + " * " + bankrupt[j] + " = " + prob * bankrupt[j]  );
                            prob *= bankrupt[j];
                            
                        }
                        else {
                            //System. out.println( " prob = " + i + " " + j + " = " +  prob + " * " + ( 1 - bankrupt[j] ) );
                            //System. out.println( " prob = " + i + " " + j + " = " + prob + " * " + ( 1 - bankrupt[j] ) + " = " + prob * ( 1 - bankrupt[j] )  );
                            prob *= 1 - bankrupt[j]; 
                        }
                        //System.out.println( "prob total " + i + " " + prob );
                    }
                    /*System.out.println("************************************************");
                    System.out.println( " y " + i + " = " + y + " * " + prob + " = " + y * prob );
                    System.out.println("************************************************");*/
                    //Sum+= y * prob;
                    Sum+= u * prob;
                }
		
		if ( Sum > SumMax ) {
			SumMax = Sum;
                        
			//System.out.println("MAXSum "+SumMax);
			//Write();
			//wALabel[0].setText("" + it); // Iterations
			//wALabel[Length + 2].setText("" + Round(SumMax)); // Iterations
                        //System.out.println( "Nauja suma  = " + SumMax );
                        for( int i = 0; i < x.length; i++ ) {
                            //System.out.println( "Koeficieintas " + i + " = " + x[i] );
                            result[i] = x[i];
                        }
			wItVector.addElement(new Integer(it));
			wFVector.addElement(new Double(SumMax));
                        this.Counter.Counter_sum_max = SumMax;
			/*if (FrameCreated)
				mGraphics.repaint();*/
		}
                
		Wait(it); // Thrred Control
		return -1 * SumMax;
	}

	double Round(double value) {
		long w = 100000000;
		return (double) Math.round(value * w) / w;
	}

	public void Data(Vector wItVector, Vector wFVector) {
		this.wItVector = wItVector;
		this.wFVector = wFVector;
	}
        /*
	public void FrameD() {
		FrameCreated = false;
	}
        * */
	void Wait(int i) {
		try {
			Thread.sleep(10); // Pause
		} catch (InterruptedException ie) {
		};
		if (StopStatus) {
			//Finished();
			Counter.stop();
		}
		if ((SuspendStatus) && (Iterations != i))
			Suspend();
	}

	// -----------------------------------------------------------------
	// -------------- Thread Control -----------------------------------

	void Finished() // Inside thread
	{
            System.out.println( " Sharp counter finished  " );
             System.out.println( "Nauja suma  = " + SumMax );
             System.out.println( "Iteracijos = " + it );
                for( int i = 0; i < x.length; i++ ) {
                    result[i] = x[i];
                    System.out.println( "Koeficieintas " + i + " = " + x[i] );
                }
	}

	public void FinishedCounter() // Outside Thread
	{
		if (SuspendStatus) {
			//Finished();
			Counter.stop();
		}
		StopStatus = true;
	}

	public void StartedCounter() {
	}

	public void Suspend() {
		Counter.suspend();
	}

	public void SuspendCounter() {
		SuspendStatus = true;
	}

	public void ResumeCounter() {
		SuspendStatus = false;
		Counter.resume();
	}
        public double getSumMax() {
            return SumMax;
        }
}
