package com.one.vector;

import javax.microedition.lcdui.Graphics;
import java.io.*;

public class PolygonArray extends VectorElement
{
	protected double[][][] data;
	protected int[][][] sdata;
	protected int[] colors;
	protected ArrayData clr, x, y, width, height, rotation, angle;
	protected int count, polycount;
	
	public PolygonArray()
	{
		clr = new ArrayData();
		x = new ArrayData();
		y = new ArrayData();
		width = new ArrayData();
		height = new ArrayData();
		rotation = new ArrayData();
		angle = new ArrayData();
		polycount = 3;
		
		count = 2;
	}
	
	public void read(DataInputStream dis) throws IOException
	{
		name = dis.readUTF();
		parseFlag(dis.readUnsignedByte());
		
		count = dis.readUnsignedShort();
		
		clr = new ArrayData(dis);
		x = new ArrayData(dis);
		y = new ArrayData(dis);
		width = new ArrayData(dis);
		height = new ArrayData(dis);
		rotation = new ArrayData(dis);
		angle = new ArrayData(dis);
		polycount = dis.readUnsignedShort();
		
		readTransformList(dis);
	}
	
	public void write(DataOutputStream dos) throws IOException
	{
		dos.writeUTF(name);
		dos.writeByte(getFlag());
		
		dos.writeShort(count);
		
		clr.write(dos);
		x.write(dos);
		y.write(dos);
		width.write(dos);
		height.write(dos);
		rotation.write(dos);
		angle.write(dos);
		dos.writeShort(polycount);
		
		writeTransformList(dos);
	}
	
	public void create()
	{
		colors = AuxMath.linearArrayRGB(clr, count);
		
		double[][] r1 = new double[4][];
		
		r1[0] = AuxMath.specificArrayFloat(x, count);
		r1[1] = AuxMath.specificArrayFloat(y, count);
		r1[2] = AuxMath.specificArrayFloat(width, count);
		r1[3] = AuxMath.specificArrayFloat(height, count);
		
		int[][] r2 = new int[2][];
		
		r2[0] = AuxMath.specificArrayInt(rotation, count);
		r2[1] = AuxMath.specificArrayInt(angle, count);
		
		data = new double[count][][];
		
		for(int i = 0; i < count; i++)
		{
			data[i] = AuxMath.plotPolygon(r1[0][i], r1[1][i], r1[2][i], r1[3][i], polycount, r2[0][i], r2[1][i]);
		}
		
		sdata = new int[count][polycount][2];
	}
	
	public void rescale()
	{
		for(int j = 0; j < count; j++)
		{
			for(int i = 0; i < polycount; i++)
			{
				sdata[j][i][0] = getScaled(data[j][i][0], 0);
				sdata[j][i][1] = getScaled(data[j][i][1], 1);
			}
		}
	}
	
	public void paint(Graphics g)
	{
		if(hidden)
		{
			return;
		}
		
		g.setStrokeStyle(stroke);
		
		int i, j;
		
		if(group.image.usecolor)
		{
			if(fill)
			{
				for(j = 0; j < count; j++)
				{
					g.setColor(colors[j]);
					
					for(i = 2; i < polycount; i++)
					{
						g.fillTriangle(sdata[j][0][0], sdata[j][0][1], sdata[j][i][0], sdata[j][i][1], sdata[j][i - 1][0], sdata[j][i - 1][1]);
					}
				}
			}
			else
			{
				for(j = 0; j < count; j++)
				{
					g.setColor(colors[j]);
					
					for(i = 1; i < data.length; i++)
					{
						g.drawLine(sdata[j][i][0], sdata[j][i][1], sdata[j][i - 1][0], sdata[j][i - 1][1]);
					}
					
					i--;
					
					g.drawLine(sdata[j][0][0], sdata[j][0][1], sdata[j][i][0], sdata[j][i][1]);
				}
			}
		}
		else
		{
			if(fill)
			{
				for(j = 0; j < count; j++)
				{
					for(i = 2; i < polycount; i++)
					{
						g.fillTriangle(sdata[j][0][0], sdata[j][0][1], sdata[j][i][0], sdata[j][i][1], sdata[j][i - 1][0], sdata[j][i - 1][1]);
					}
				}
			}
			else
			{
				for(j = 0; j < count; j++)
				{
					for(i = 1; i < data.length; i++)
					{
						g.drawLine(sdata[j][i][0], sdata[j][i][1], sdata[j][i - 1][0], sdata[j][i - 1][1]);
					}
					
					i--;
					
					g.drawLine(sdata[j][0][0], sdata[j][0][1], sdata[j][i][0], sdata[j][i][1]);
				}
			}
		}
	}
	
	public void update(boolean flag, boolean changed)
	{
		Transform transform;
		int param, subparam;
		ArrayData v;
		
		for(int i = 0; i < transcount; i++)
		{
			transform = (Transform)transforms.elementAt(i);
			transform.setFrame(group.image.frame);
			
			if(transform.isApplied())
			{
				param = transform.getParam();
				
				if(param == SHOW)
				{
					setHidden(AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition()));
				}
				else
				{
					subparam = transform.getSubParam();
					
					if(subparam == 0)
					{
						if(param == INT_A)
						{
							clr.inta = AuxMath.linearFunctionRGB(transform.getData(), transform.getPosition());
						}
						else if(param == INT_B)
						{
							clr.intb = AuxMath.linearFunctionRGB(transform.getData(), transform.getPosition());
						}
						
						continue;
					}
					else if(subparam == 1)
					{
						v = x;
					}
					else if(subparam == 2)
					{
						v = y;
					}
					else if(subparam == 3)
					{
						v = width;
					}
					else if(subparam == 4)
					{
						v = height;
					}
					else if(subparam == 5)
					{
						v = rotation;
					}
					else if(subparam == 6)
					{
						v = angle;
					}
					else
					{
						continue;
					}
					
					switch(param)
					{
						case VAL_A:
							v.vala = AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition());
							changed = true;
							break;
						
						case VAL_B:
							v.valb = AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition());
							changed = true;
							break;
						
						case DIV_A:
							v.diva = AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition());
							changed = true;
							break;
						
						case DIV_B:
							v.divb = AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition());
							changed = true;
							break;
						
						case DIV_C:
							v.divc = AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition());
							changed = true;
							break;
						
						case DIV_D:
							v.divd = AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition());
							changed = true;
							break;
						
						case INT_A:
							v.inta = AuxMath.specificFunctionInt(transform.getData(), transform.getPosition());
							changed = true;
							break;
						
						case INT_B:
							v.intb = AuxMath.specificFunctionInt(transform.getData(), transform.getPosition());
							changed = true;
							break;
					}
				}
			}
		}
		
		if(flag && changed)
		{
			create();
			rescale();
		}
	}
	
	public Object getValue(int param, int subparam)
	{
		if(param == COUNT)
		{
			return new Integer(count);
		}
		else if(param == POLY_COUNT)
		{
			return new Integer(polycount);
		}
		
		ArrayData v;
		
		if(subparam == 0)
		{
			v = clr;
		}
		else if(subparam == 1)
		{
			v = x;
		}
		else if(subparam == 2)
		{
			v = y;
		}
		else if(subparam == 3)
		{
			v = width;
		}
		else if(subparam == 4)
		{
			v = height;
		}
		else if(subparam == 5)
		{
			v = rotation;
		}
		else if(subparam == 6)
		{
			v = angle;
		}
		else
		{
			return null;
		}
		
		switch(param)
		{
			case VAL_A:
				return new Double(v.vala);
			
			case VAL_B:
				return new Double(v.valb);
			
			case DIV_A:
				return new Double(v.diva);
			
			case DIV_B:
				return new Double(v.divb);
			
			case DIV_C:
				return new Double(v.divc);
			
			case DIV_D:
				return new Double(v.divd);
			
			case INT_A:
				return new Integer(v.inta);
			
			case INT_B:
				return new Integer(v.intb);
			
			case FUNCTION:
				return new Integer(v.type);
		}
		
		return null;
	}
	
	public void setValue(Object value, int param, int subparam)
	{
		if(param == COUNT)
		{
			count = ((Integer)value).intValue();
			return;
		}
		else if(param == POLY_COUNT)
		{
			polycount = ((Integer)value).intValue();
			return;
		}
		
		ArrayData v;
		
		if(subparam == 0)
		{
			v = clr;
		}
		else if(subparam == 1)
		{
			v = x;
		}
		else if(subparam == 2)
		{
			v = y;
		}
		else if(subparam == 3)
		{
			v = width;
		}
		else if(subparam == 4)
		{
			v = height;
		}
		else if(subparam == 5)
		{
			v = rotation;
		}
		else if(subparam == 6)
		{
			v = angle;
		}
		else
		{
			return;
		}
		
		switch(param)
		{
			case VAL_A:
				v.vala = ((Double)value).doubleValue();
				break;
			
			case VAL_B:
				v.valb = ((Double)value).doubleValue();
				break;
			
			case DIV_A:
				v.diva = ((Double)value).doubleValue();
				break;
			
			case DIV_B:
				v.divb = ((Double)value).doubleValue();
				break;
			
			case DIV_C:
				v.divc = ((Double)value).doubleValue();
				break;
			
			case DIV_D:
				v.divd = ((Double)value).doubleValue();
				break;
			
			case INT_A:
				v.inta = ((Integer)value).intValue();
				break;
			
			case INT_B:
				v.intb = ((Integer)value).intValue();
				break;
			
			case FUNCTION:
				v.type = ((Integer)value).intValue();
				break;
		}
	}
}