package com.one.vector;

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

public class ThickPolygon extends VectorElement
{
	protected ThickLine[] lines;
	protected ArrayData pdata;
	protected int count;
	protected double thickness;
	
	public ThickPolygon()
	{
		pdata = new ArrayData();
		pdata.type = ArrayData.HARMONIC;
		
		count = 3;
		
		thickness = 0;
	}
	
	public void read(DataInputStream dis) throws IOException
	{
		name = dis.readUTF();
		color = dis.readInt();
		parseFlag(dis.readUnsignedByte());
		
		pdata = new ArrayData(dis);
		count = dis.readUnsignedShort();
		thickness = dis.readFloat();
		
		readTransformList(dis);
	}
	
	public void write(DataOutputStream dos) throws IOException
	{
		dos.writeUTF(name);
		dos.writeInt(color);
		dos.writeByte(getFlag());
		
		pdata.write(dos);
		dos.writeShort(count);
		dos.writeFloat((float)thickness);
		
		writeTransformList(dos);
	}
	
	public void create()
	{
		double[][] data = AuxMath.plotPolygon(pdata.vala, pdata.valb, pdata.diva, pdata.divb, count, pdata.inta, pdata.intb);

		lines = new ThickLine[data.length];
		
		lines[0] = new ThickLine(color, NORMAL, data[data.length - 1][0], data[data.length - 1][1], data[0][0], data[0][1], thickness);
		lines[0].setGroup(group);
		
		for(int i = 1; i < lines.length; i++)
		{
			lines[i] = new ThickLine(color, NORMAL, data[i - 1][0], data[i - 1][1], data[i][0], data[i][1], thickness);
			lines[i].setGroup(group);
		}
	}
	
	public void rescale()
	{
		for(int i = 0; i < lines.length; i++)
		{
			lines[i].rescale();
		}
	}
	
	public void setGroup(Group grp)
	{
		super.setGroup(grp);
		
		for(int i = 0; i < lines.length; i++)
		{
			lines[i].setGroup(grp);
		}
	}
	
	public void paint(Graphics g)
	{
		if(hidden)
		{
			return;
		}
		
		for(int i = 0; i < lines.length; i++)
		{
			lines[i].paint(g);
		}
	}
	
	public void update(boolean flag, boolean changed)
	{
		Transform transform;
		int param;
		
		for(int i = 0; i < transcount; i++)
		{
			transform = (Transform)transforms.elementAt(i);
			transform.setFrame(group.image.frame);
			
			if(transform.isApplied())
			{
				param = transform.getParam();
				
				switch(param)
				{
					case SHOW:
						setHidden(AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition()));
						break;
					
					case COLOR:
						color = AuxMath.linearFunctionRGB(transform.getData(), transform.getPosition());
						changed = true;
						break;
					
					case X:
						pdata.vala = AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition());
						changed = true;
						break;
					
					case Y:
						pdata.valb = AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition());
						changed = true;
						break;
					
					case WIDTH:
						pdata.diva = AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition());
						changed = true;
						break;
					
					case HEIGHT:
						pdata.divb = AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition());
						changed = true;
						break;
					
					case ROTATION:
						pdata.inta = AuxMath.specificFunctionInt(transform.getData(), transform.getPosition());
						changed = true;
						break;
					
					case ANGLE:
						pdata.intb = AuxMath.specificFunctionInt(transform.getData(), transform.getPosition());
						changed = true;
						break;
					
					case THICKNESS:
						thickness = AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition());
						changed = true;
						break;
				}
			}
		}
		
		if(flag && changed)
		{
			create();
			rescale();
		}
	}
	
	public Object getValue(int param, int subparam)
	{
		switch(param)
		{
			case X:
				return new Double(pdata.vala);
			
			case Y:
				return new Double(pdata.valb);
			
			case WIDTH:
				return new Double(pdata.diva);
			
			case HEIGHT:
				return new Double(pdata.divb);
			
			case ROTATION:
				return new Integer(pdata.inta);
			
			case ANGLE:
				return new Integer(pdata.intb);
			
			case POLY_COUNT:
				return new Integer(count);
			
			case THICKNESS:
				return new Double(thickness);
		}
		
		return null;
	}
	
	public void setValue(Object value, int param, int subparam)
	{
		switch(param)
		{
			case X:
				pdata.vala = ((Double)value).doubleValue();
				break;
			
			case Y:
				pdata.valb = ((Double)value).doubleValue();
				break;
			
			case WIDTH:
				pdata.diva = ((Double)value).doubleValue();
				break;
			
			case HEIGHT:
				pdata.divb = ((Double)value).doubleValue();
				break;
			
			case ROTATION:
				pdata.inta = ((Integer)value).intValue();
				break;
			
			case ANGLE:
				pdata.intb = ((Integer)value).intValue();
				break;
			
			case POLY_COUNT:
				count = ((Integer)value).intValue();
				break;
			
			case THICKNESS:
				thickness = ((Double)value).doubleValue();
				break;
		}
	}
	
	public void writeSVG(PrintStream ps)
	{
		double[][] data = AuxMath.plotPolygon(pdata.vala, pdata.valb, pdata.diva, pdata.divb, count, pdata.inta, pdata.intb);
		
		ps.print("\t\t\t<polygon");
		
		ps.print(" points=\"");
		ps.print(Integer.toString(getScaled(data[0][0], 0)) + " " + Integer.toString(getScaled(data[0][1], 1)));
		
		for(int i = 1; i < data.length; i++)
		{
			ps.print(", " + Integer.toString(getScaled(data[i][0], 0)) + " " + Integer.toString(getScaled(data[i][1], 1)));
		}
		
		ps.print("\"");
		
		ps.print(" stroke-width=\"" + Integer.toString(getScaled(thickness, 4)) + "\"");
		ps.print(" stroke-linejoin=\"round\"");
		
		writeSVGTail(ps, false, false);
		
		ps.println("/>");
	}
}