package lt.ktu.gmj.tasks;

//import lt.ktu.gmj.tasks.*;

import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.JTabbedPane;

import lt.ktu.gmj.Domain;
import lt.ktu.gmj.Point;
import lt.ktu.gmj.Task;
import defaultPackage.MeGraphics;

public class MePortfolio /*implements Task */{
	
        private Domain domain = new Domain();

	int Iterations, InitialPoint, BankLength, ShareLength;
        
	double AllBankrupt[], AllDividends[], x[], ObjectValue[];
        double Uf[] = { 0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0 };

	double Resours;

	int InType;

	String mMethod;

	Thread Counter;

	Vector wItVector, wFVector;

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

	/*double naud_f[][] = { { 0.0, 0.0, 0.0, 0.0, 0.0 },
			{ 0.5, 0.025, 0.125, 0.025, 0.0 },
			{ 0.675, 0.05, 0.25, 0.075, 0.0 }, 
                        { 0.775, 0.1, 0.375, 0.2, 0.0 },
			{ 0.85, 0.15, 0.5, 0.5, 0.0 }, 
                        { 0.9, 0.225, 0.625, 0.8, 0.0 },
			{ 0.95, 0.325, 0.75, 0.925, 0.0 },
			{ 0.975, 0.5, 0.875, 0.975, 0.0 }, 
                        { 1.0, 1.0, 1.0, 1.0, 1.0 } };*/

	// double yk[] = {0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2.0};
	//double yk[] = new double[9]; // = {0, 0.13, 0.26, 0.39, 0.52, 0.65, 0.78,

	// 0.91, 1.0};
	// ------------------------------

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

	double SumMax = 0.0;

	public MePortfolio() {
            //System.out.println( "protfolio me constructor " );
	}
        public void setParameters( int Iterations[], int InType, double Resours,
			double AllBankrupt[], double AllDividends[],
			double  result[], int BankLength, int ShareLength,
			double ObjectValue[], String mMethod, double Uf[])/*
	public void setParameters(int Iterations[], int InType, double Resours,
			double AllBankrupt[], double AllDividends[],
			JProgressBar wProgressBar, JLabel wALabel[],
			JTabbedPane wTabbedPane, JButton w1Button, JButton w2Button,
			int BankLength, int ShareLength, int InsuranceLength,
			double ObjectValue[], String mMethod, double Uf[]) */{
		this.Iterations = Iterations[0];
		this.InitialPoint = Iterations[1];
		this.InType = InType;
		this.Resours = Resours;
		this.AllBankrupt = AllBankrupt;
		this.AllDividends = AllDividends;
		this.BankLength = BankLength;
		this.ShareLength = ShareLength;
		this.ObjectValue = ObjectValue;
		this.mMethod = mMethod;
		/*if (InType == 0)
			Risk = 3; // Real
		else if (InType == 1)
			Risk = 0; // Prudent
		else if (InType == 2)
			Risk = 1; // Risk
		else if (InType == 3)
			Risk = 2; // Rich
		else if (InType == 4) {
			Risk = 4; // User
			for (int i = 0; i < 9; i++)
				naud_f[i][Risk] = this.Uf[i];
		}*/
		Length = AllDividends.length;
		//SetYk();
	}
        /*
	void SetYk() {
		double max = 0.0;
		for (int i = 0; i < Length; i++)
			if (max < (AllDividends[i] - 1))
				max = AllDividends[i] - 1;
		max = max / 8;
		for (int i = 0; i < 9; i++)
			yk[i] = Round(i * max);
	}
        */ 
	public Domain domain() {
		return domain;
	}

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

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

	public double f(Point pt) {
		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;
		double Sum = 0.0;
		int Power = (int) Math.pow(2, Length);
		// if ((AllOk(Risk) == Length) && (Zok() == InsuranceLength)) // Ar
		// tinka visi sugeneruoti x pagal zogaus naudingumo funkcija ir ar
		// draudimo z>=x
                //System.out.println( "power " + Power );
                //System.out.println( "Risk " + Risk );
                ///System.out.println( "naud_f length " + naud_f.length );
                //System.out.println( "naud_f length[risk] " + naud_f[Risk].length );
                //System.out.println( "Yk legth " + yk.length );
                                
		//if ((Zok() == InsuranceLength)) // Ar tinka visi sugeneruoti x pagal
                // zogaus naudingumo funkcija ir ar
                // draudimo z>=x
                for (int i = 0; i < Power; i++) // Deterministic metod (perrenkami
                // visi galimi dankrotai ir
                // islikimai)
                {
                    double z = 0.0, P = 1.0;
                    for (int j = 0; j < Length; j++) // z = for year
                    {
                            if ((i & (1 << (j))) != 0) {
                                    z += (AllDividends[j] - 1) * x[j];
                                    P *= AllBankrupt[j];
                            } else {
                                    P *= 1 - AllBankrupt[j];
                            }
                    }
                    int ji = 0;
                   // for (int k = 0; k < 8; k++) {
                    //        if (z >= yk[k]) ji = ji + 1;
                            //System.out.println( z + " > = " + yk[k]);
                   // }// Nustato vieta naudingumo funkcijoje

                    double Naud = 0.0;
                    // System.out.println(" Z "+z+" AllDividends "+AllDividends[0]+"
                    // 2 "+AllDividends[1]);
                    /*System.out.println(ji);
                    System.out.println(naud_f[ji][Risk]);
                    System.out.println(naud_f[ji - 1][Risk]);
                    System.out.println(yk[ji]);
                    System.out.println(yk[ji - 1]);
                    System.out.println(  "Naud = ((( " + naud_f[ji][Risk] + " - " + naud_f[ji - 1][Risk] + " ) * ( " + z +
                            "- " +yk[ji - 1]+")) / ( " +yk[ji]+" - "+yk[ji - 1]+") + " + naud_f[ji - 1][Risk] + ")"  );*/
                   // if ( ji > 0 ) Naud = (((naud_f[ji][Risk] - naud_f[ji - 1][Risk]) * (z - yk[ji - 1]))
                    //                / (yk[ji] - yk[ji - 1]) + naud_f[ji - 1][Risk]);
                    // System.out.println("It "+it+" Z "+z+" Naud "+Naud+" P "+P);
                    if (Risk == 0)
                            Sum += Naud * P; // Prudent
                    if (Risk == 1)
                            Sum += Naud * P; // Risk
                    if (Risk == 2)
                            Sum += Naud * P; // Rich
                    if (Risk == 3)
                            Sum += Naud * P; // Real
                    if (Risk == 4)
                            Sum += Naud * P; // Real
                    Sum = this.Round(Sum);
                }
		if (Sum > SumMax) {
                    SumMax = Sum;
                    // System.out.println("MAXSum "+SumMax);
                    Write();
                    //wALabel[0].setText("" + it); // Iterations
                    //wALabel[Length + 2].setText("" + Round(SumMax)); // Iterations
                    wItVector.addElement(new Integer(it));
                    wFVector.addElement(new Double(SumMax));
                    /*if (FrameCreated)
                            mGraphics.repaint();*/
		}
		Wait(it); // Thrred Control
		return -1 * SumMax;
	}

	// -------- METODS -------------------------------------------
	// -------- METODS -------------------------------------------
	// -------- METODS -------------------------------------------

	double Round(double value) {
		long w = 100000000;
		return (double) Math.round(value * w) / w;
	}
        /*
	int AllOk(int Risk) {
		int Allok = 0;
		for (int i = 0; i < Length; i++) {
			int ji = 0;
			double z = x[i];
			for (int k = 0; k < 8; k++)
				if (z >= yk[k])
					ji = ji + 1;
			double Naud = ((naud_f[ji][Risk] - naud_f[ji - 1][Risk]) * (z - yk[ji - 1]))
					/ (yk[ji] - yk[ji - 1]) + naud_f[ji - 1][Risk];
			if ((AllBankrupt[i] >= Naud))
				Allok = Allok + 1;
		}
		return Allok;
	}
/*
	int Zok() {
		if (InsuranceLength == 0) return 0;
		int Allok = 0, k;
		for (int i = 0; i < InsuranceLength; i++) {
			k = BankLength + ShareLength + i;
			if (ObjectValue[i] >= x[k] * AllDividends[k])
				Allok = Allok + 1;
		}
		return Allok;
	}
*/
	// ----------------- Write To Screen -------------------
	void Write() {
		double Sum = 0;
		for (int j = 0; j < Length; j++) {
			double d = Math.round(AllDividends[j] * Resours * x[j] * 100);
			d = d / 100;
			Sum = Sum + d;
		}
		Sum = Math.round(Sum * 100);
		Sum = Sum / 100;
		//wALabel[Length + 1].setText("" + Sum);
		for (int j = 0; j < Length; j++) // Write to screen
		{
			double d = Math.round(Resours * x[j] * 100);
			d = d / 100;
			//wALabel[j + 1].setText("" + d);
		}
	}

	public void Data(Vector wItVector, Vector wFVector) {
		this.wItVector = wItVector;
		this.wFVector = wFVector;
	}
/*
	public void FrameC(MeGraphics mGraphics) {
		this.mGraphics = mGraphics;
		FrameCreated = true;
	}
*/
	public void FrameD() {
		FrameCreated = false;
	}

	// ------------------------------------------------

	void Wait(int i) {
		//wProgressBar.setValue(i); // ProgresBar
		try {
			Thread.sleep(10); // Pause
		} catch (InterruptedException ie) {
		}
		;
		if (StopStatus) {
			Finished();
			Counter.stop();
		}
		if ((SuspendStatus) && (Iterations != i))
			Suspend();
	}

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

	void Finished() // Inside thread
	{
		/*wTabbedPane.setEnabledAt(0, true);
		if (InType == 4)
			wTabbedPane.setEnabledAt(1, true);
		wTabbedPane.setEnabledAt(2, true);
		wTabbedPane.setEnabledAt(3, true);
		wTabbedPane.setEnabledAt(4, true);*/
		/*
                w2Button.setEnabled(false);
		w2Button.setToolTipText(null);
		w1Button.setText("Pradeti");
		w1Button.setToolTipText("Pradeti investiciju skaiciavima");
                */
                /*for ( int i = 0; i < wALabel.length ; i++ ) {
                    System.out.println( "walabel " + i );
                    System.out.println( wALabel[i].getText() );
                }*/
	}

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

	public void StartedCounter() {
		/*wTabbedPane.setEnabledAt(0, false);
		wTabbedPane.setEnabledAt(1, false);
		wTabbedPane.setEnabledAt(2, false);
		wTabbedPane.setEnabledAt(3, false);
		wTabbedPane.setEnabledAt(4, false);*/
		/*
                w1Button.setText("Pristabdyti");
		w1Button.setToolTipText("Pristabdyti investiciju skaiciavima");
		w2Button.setEnabled(true);
		w2Button.setToolTipText("Sustabdyti investiciju skaiciavima");*/
	}

	public void Suspend() {
		/*w1Button.setText("Testi");
		w1Button.setToolTipText("Testi investiciju skaiciavima");*/
		Counter.suspend();
	}

	public void SuspendCounter() {
		SuspendStatus = true;
	}

	public void ResumeCounter() {
		SuspendStatus = false;
		/*w1Button.setText("Pristabdyti");
		w1Button.setToolTipText("Pristabdyti investiciju skaiciavima");*/
		Counter.resume();
	}

}
