package endu;

import vtk.*;
import battery.graph.GraphPanel;

public class simulation {
	public static int textOffset=300;
	public static vtkActor2D[] percentActor;
	public static vtkTextActor processTextActor = new vtkTextActor();
	
	public static vtkTextActor[] valueActor = new vtkTextActor[8];
	public static vtkTextActor[] dateActor = new vtkTextActor[8];

	public static void startSim() {
		System.out.println("");

		for (int measure = 0; measure < 8; measure++) {
			if (util.isMeasureUsed(measure) >= 0) {
				for (int i = 0; i < ReadCSV.numRow; i = i
						+ EnduModel.dataReduction1) {
					EnduModel.ren.RemoveActor(EnduModel.actorArray[measure][i]);
				}
			}
		}

		String str = GraphPanel.simSpeed.getValue().toString();
		int speed = Integer.parseInt(str);
		System.out.println("++++++++ SIMULATION STARTED at SPEED " + speed);

		percentActor = new vtkActor2D[ReadCSV.numRow];
		addPercentText();
		
		for (int i = 0; i < ReadCSV.numRow; i = i + EnduModel.dataReduction2) {
			int numOfMeasure=0;
			for (int measure = 0; measure < 8; measure++) {
				if (util.isMeasureUsed(measure) < 0)
					continue;
				
				int color = util.isMeasureUsed(measure);
				double min = util.getMin(ReadCSV.arrayMeasure[measure]);
				double max = util.getMax(ReadCSV.arrayMeasure[measure]);

				if (i % speed == 0) {
					if (numOfMeasure== 0) {	
						addSimPercent(i, speed);
					}
					numOfMeasure++;
					
					EnduModel.ren.RemoveActor(valueActor[measure]);
					EnduModel.ren.RemoveActor(dateActor[measure]);
					addMeasureValue(measure, util.isMeasureUsed(measure), i);
					addMeasureTime(measure, util.isMeasureUsed(measure), i);
					
					
					EnduModel.renWin.Render();
					EnduModel.ren.GetActiveCamera().Azimuth(0.1);
					util.updateVTK();
		
					
				}

				vtkSphereSource s = new vtkSphereSource();
				s.SetRadius(EnduModel.radius);
				s.SetCenter(ReadCSV.arrayY.GetValue(i) / EnduModel.scaleXY
						+ EnduModel.radius * EnduModel.measureSlot[measure],
						ReadCSV.arrayX.GetValue(i) / EnduModel.scaleXY,
						ReadCSV.arrayDepth.GetValue(i) / EnduModel.scaleDepth);
				vtkPolyDataMapper sphereMapper = new vtkPolyDataMapper();
				sphereMapper.SetInputConnection(s.GetOutputPort());
				EnduModel.actorArray[measure][i] = new vtkActor();
				EnduModel.actorArray[measure][i].SetMapper(sphereMapper);

				double saturation = 0;
				if (ReadCSV.arrayMeasure[measure].GetValue(i) == EnduModel.missingValue) {
					EnduModel.actorArray[measure][i].GetProperty().SetColor(0,
							0, 0);
				} else {
					saturation = (max - ReadCSV.arrayMeasure[measure]
							.GetValue(i))
							/ (max - min);
					double[] rgb = util.getRGB(measure, color, saturation);
					EnduModel.actorArray[measure][i].GetProperty().SetColor(
							rgb[0], rgb[1], rgb[2]);
				}
				EnduModel.ren.AddActor(EnduModel.actorArray[measure][i]);
			}
		}
		endSim(speed);
	}
	public static void endSim(int speed) {
		for (int i = 0; i < ReadCSV.numRow; i+=EnduModel.dataReduction2) {
			EnduModel.ren.RemoveActor(percentActor[i]);
		}
		for (int measure = 0; measure < 8; measure++) {
			if (util.isMeasureUsed(measure) >= 0){
				EnduModel.ren.RemoveActor(valueActor[measure]);
				EnduModel.ren.RemoveActor(dateActor[measure]);
	
			}
		}
		EnduModel.ren.RemoveActor(processTextActor);	
	}
		
	public static void addPercentText() {
		processTextActor = new vtkTextActor();
		processTextActor.SetDisplayPosition(textOffset,8);
		processTextActor.SetInput("Process:");
		processTextActor.GetPosition2Coordinate()
				.SetCoordinateSystemToNormalizedViewport();
		processTextActor.GetPosition2Coordinate().SetValue(0.2, 0.1);

		vtkTextProperty tprop = processTextActor.GetTextProperty();
		tprop.SetFontSize(16);
		tprop.SetFontFamilyToArial();
		tprop.SetJustificationToLeft();
		tprop.BoldOn();
		tprop.ItalicOn();
		tprop.ShadowOn();
		tprop.SetColor(0, 0, 0);
		EnduModel.ren.AddActor2D(processTextActor);
	}
	
	public static void addSimPercent(int i, int speed) {

		int index = (int) (i / (EnduModel.dataReduction2 * speed));
		int total = (int) (ReadCSV.numRow / (EnduModel.dataReduction2 * speed));
		double saturation= (double) index / (double) total;
		
		int xOffset = 364;
		double width = Main.panel.getWidth() - xOffset;
		System.out.println("simPercent index: " + index + " Total: " + total);
		System.out.println("simPercent width: " + width);


		int id = 0;
		vtkPoints points1 = new vtkPoints();
		points1.SetNumberOfPoints(2);
		while (id < 2) {
			if (id == 0) {
				points1.InsertPoint(id, xOffset
						+ ((double) index / (double) total) * width, 13, 0);
			} else {
				points1.InsertPoint(id, xOffset
						+ ((double) (index + 1) / (double) total) * width, 13,
						0);
			}
			id++;
		}

		vtk.vtkCellArray lines1 = new vtk.vtkCellArray();
		lines1.Allocate(1, 1);
		lines1.InsertNextCell(id);
		lines1.SetNumberOfCells(id);

		for (int k = 0; k < id; ++k) {
			lines1.InsertCellPoint(k);
		}
		vtkPolyData c_polyData1 = new vtkPolyData();
		c_polyData1.ReleaseDataFlagOn();
		c_polyData1.Allocate(1, 1);
		c_polyData1.SetPoints(points1);
		c_polyData1.SetLines(lines1);

		vtk.vtkPolyDataMapper2D c_polyDataMapper = new vtk.vtkPolyDataMapper2D();
		c_polyDataMapper.SetInput(c_polyData1);

		percentActor[i] = new vtkActor2D();
		// EnduModel.legendActor[m][i].GetProperty().SetOpacity(1);
		percentActor[i].GetProperty().SetLineWidth(20.0f);
		percentActor[i].SetMapper(c_polyDataMapper);
		percentActor[i].VisibilityOn();

		percentActor[i].GetProperty().SetColor((saturation), 1-saturation, 0);
		EnduModel.ren.AddViewProp(percentActor[i]);
	}

	public static void addMeasureValue(int m, int color, int i) {

		int slot = EnduModel.measureSlot[m];
		int yOffset= 35;
		int y= 12;
		
		valueActor[m] = new vtkTextActor();
		//  EnduModel.textActor[m].ScaledTextOn();
		valueActor[m].SetDisplayPosition(textOffset +38,slot*yOffset+yOffset-5+y);
		valueActor[m].SetInput(""+util.formatDouble(ReadCSV.arrayMeasure[m].GetValue(i)));
		valueActor[m].GetPosition2Coordinate().SetCoordinateSystemToNormalizedViewport();
		valueActor[m].GetPosition2Coordinate().SetValue(0.2, 0.1);

		  vtkTextProperty tprop = valueActor[m].GetTextProperty();
		  tprop.SetFontSize(16);
		  tprop.SetFontFamilyToArial();
		  tprop.SetJustificationToRight();
		  tprop.BoldOn();
		  tprop.ItalicOn();
		  tprop.ShadowOn();
		  
		  if (ReadCSV.arrayMeasure[m].GetValue(i)==-999.0){
			  tprop.SetColor(0,0,0);
		  }
		  else{
			  double [] c= util.getRGB(m, color, 0);
			  tprop.SetColor(c[0],c[1],c[2]);
		  }
		  
		  EnduModel.ren.AddActor2D(valueActor[m]);
	}
	
	public static void addMeasureTime(int m, int color, int i) {

		int slot = EnduModel.measureSlot[m];
		int yOffset= 35;
		int y= 12;
		
		dateActor[m] = new vtkTextActor();
		//  EnduModel.textActor[m].ScaledTextOn();
		dateActor[m].SetDisplayPosition(textOffset + 60,slot*yOffset+yOffset-5+y);
		dateActor[m].SetInput(""+ ReadCSV.strDate[i]+" "+ReadCSV.strTime[i]);
		dateActor[m].GetPosition2Coordinate().SetCoordinateSystemToNormalizedViewport();
		dateActor[m].GetPosition2Coordinate().SetValue(0.2, 0.1);

		  vtkTextProperty tprop = dateActor[m].GetTextProperty();
		  tprop.SetFontSize(16);
		  tprop.SetFontFamilyToArial();
		  tprop.SetJustificationToLeft();
		  tprop.BoldOn();
		  tprop.ItalicOn();
		  tprop.ShadowOn();
		  
		  if (ReadCSV.strDate[i].contains(EnduModel.missingDate)){
			  tprop.SetColor(0,0,0);
		  }
		  else{
			  double [] c= util.getRGB(m, color, 0);
			  tprop.SetColor(c[0],c[1],c[2]);
		  }
		  
		  EnduModel.ren.AddActor2D(dateActor[m]);
	}


}
