package com.one.vector;

import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import java.io.*;
import java.lang.Math;

public class TextureTriangle extends VectorElement
{
	protected double[] data = new double[6];
	protected int[] sdata = new int[6];
	
	protected double[] bounds = new double[4];
	protected int[] sbounds = new int[4];
	
	protected String filename;
	protected int[] texdata;
	protected int texwidth, texheight;
	
	protected int[] imagedata;
	protected int scanlength;
	
	protected boolean ready = false;
	
	public TextureTriangle()
	{
		data[0] = 0;
		data[1] = 0;
		data[2] = 0;
		data[3] = 0;
		data[4] = 0;
		data[5] = 0;
	}
	
	public void read(DataInputStream dis) throws IOException
	{
		name = dis.readUTF();
		color = dis.readInt();
		parseFlag(dis.readUnsignedByte());
		
		data[0] = dis.readFloat();
		data[1] = dis.readFloat();
		data[2] = dis.readFloat();
		data[3] = dis.readFloat();
		data[4] = dis.readFloat();
		data[5] = dis.readFloat();
		
		System.gc();
		
		try
		{
			if(dis.readBoolean())
			{
				int blen = dis.readInt();
				byte[] b = new byte[blen];
				
				dis.readFully(b);
				Image texture = Image.createImage(b, 0, blen);
				b = null;
				
				texwidth = texture.getWidth();
				texheight = texture.getHeight();
				
				System.gc();
				texdata = new int[texwidth * texheight];
				texture.getRGB(texdata, 0, texwidth, 0, 0, texwidth, texheight);
			}
			else
			{
				texwidth = dis.readInt();
				texheight = dis.readInt();
				
				texdata = new int[texwidth * texheight];
				
				for(int i = 0; i < texdata.length; i++)
				{
					texdata[i] = dis.readInt();
				}
			}
		}
		catch(OutOfMemoryError oome)
		{
			texwidth = Bitmap.DEFTEX_WIDTH;
			texheight = Bitmap.DEFTEX_HEIGHT;
			
			texdata = new int[texwidth * texheight];
			
			for(int i = 0; i < texdata.length; i++)
			{
				texdata[i] = color;
			}
		}
		
		readTransformList(dis);
	}
	
	public void write(DataOutputStream dos) throws IOException
	{
		dos.writeUTF(name);
		dos.writeInt(color);
		dos.writeByte(getFlag());
		
		dos.writeFloat((float)data[0]);
		dos.writeFloat((float)data[1]);
		dos.writeFloat((float)data[2]);
		dos.writeFloat((float)data[3]);
		dos.writeFloat((float)data[4]);
		dos.writeFloat((float)data[5]);
		
		try
		{
			InputStream is = Connector.openInputStream("file:///" + filename);
			
			byte[] b = new byte[4096];
			
			dos.writeBoolean(true);
			dos.writeInt(is.available());
			
			while(is.available() > 0)
			{
				dos.write(b, 0, is.read(b));
			}
			
			is.close();
		}
		catch(Exception e)
		{
			dos.writeBoolean(false);
			dos.writeInt(texwidth);
			dos.writeInt(texheight);
			
			for(int i = 0; i < texdata.length; i++)
			{
				dos.writeInt(texdata[i]);
			}
		}
		
		writeTransformList(dos);
	}
	
	public void create()
	{
		bounds[0] = Math.min(data[0], Math.min(data[2], data[4]));
		bounds[1] = Math.min(data[1], Math.min(data[3], data[5]));
		bounds[2] = Math.max(data[0], Math.max(data[2], data[4])) - bounds[0];
		bounds[3] = Math.max(data[1], Math.max(data[3], data[5])) - bounds[1];
		
		if(texdata == null)
		{
			try
			{
				InputStream is = Connector.openInputStream("file:///" + filename);
				Image texture = Image.createImage(is);
				is.close();
				
				System.gc();
				
				texwidth = texture.getWidth();
				texheight = texture.getHeight();
				
				texdata = new int[texwidth * texheight];
				texture.getRGB(texdata, 0, texwidth, 0, 0, texwidth, texheight);
			}
			catch(Throwable t)
			{
				texwidth = Bitmap.DEFTEX_WIDTH;
				texheight = Bitmap.DEFTEX_HEIGHT;
				
				texdata = new int[texwidth * texheight];
				
				for(int i = 0; i < texdata.length; i++)
				{
					texdata[i] = color;
				}
			}
		}
	}
	
	public void rescale()
	{
		sbounds[0] = getScaled(bounds[0], 0);
		sbounds[1] = getScaled(bounds[1], 1);
		sbounds[2] = getScaled(bounds[2], 2);
		sbounds[3] = getScaled(bounds[3], 3);
		
		sdata[0] = getScaled(data[0] - bounds[0], 0);
		sdata[1] = getScaled(data[1] - bounds[1], 1);
		sdata[2] = getScaled(data[2] - bounds[0], 0);
		sdata[3] = getScaled(data[3] - bounds[1], 1);
		sdata[4] = getScaled(data[4] - bounds[0], 0);
		sdata[5] = getScaled(data[5] - bounds[1], 1);
		
		ready = false;
		
		try
		{
			int repx = (sbounds[2] + texwidth - 1) / texwidth;
			int repy = (sbounds[3] + texheight - 1) / texheight;
			
			scanlength = texwidth * repx;
			
			System.gc();
			imagedata = new int[scanlength * texheight * repy];
			
			int i, j, k;
			
			for(i = 0; i < repx; i++)
			{
				for(j = 0; j < repy; j++)
				{
					for(k = 0; k < texheight; k++)
					{
						System.arraycopy(texdata, texwidth * k, imagedata, texwidth * i + (texheight * j + k) * scanlength, texwidth);
					}
				}
			}
			
			Image temp = Image.createImage(sbounds[2], sbounds[3]);
			Graphics g = temp.getGraphics();
			
			g.setColor(0);
			g.fillRect(0, 0, sbounds[2], sbounds[3]);
			g.setColor(0xFFFFFFFF);
			g.fillTriangle(sdata[0], sdata[1], sdata[2], sdata[3], sdata[4], sdata[5]);
			
			System.gc();
			int[] shapedata = new int[imagedata.length];
			temp.getRGB(shapedata, 0, scanlength, 0, 0, sbounds[2], sbounds[3]);
			
			for(i = 0; i < shapedata.length; i++)
			{
				if((shapedata[i] & 0xFFFFFF) == 0)
				{
					imagedata[i] = 0;
				}
			}
			
			ready = true;
		}
		catch(Throwable t)
		{
			sdata[0] = getScaled(data[0], 0);
			sdata[1] = getScaled(data[1], 1);
			sdata[2] = getScaled(data[2], 0);
			sdata[3] = getScaled(data[3], 1);
			sdata[4] = getScaled(data[4], 0);
			sdata[5] = getScaled(data[5], 1);
		}
		
		System.gc();
	}
	
	public void paint(Graphics g)
	{
		if(hidden)
		{
			return;
		}
		
		if(ready && group.image.usecolor)
		{
			g.drawRGB(imagedata, 0, scanlength, sbounds[0], sbounds[1], sbounds[2], sbounds[3], true);
		}
		else
		{
			if(group.image.usecolor)
			{
				g.setColor(color);
			}
			
			g.fillRoundRect(sdata[0], sdata[1], sdata[2], sdata[3], sdata[4], sdata[5]);
		}
	}
	
	public void update(boolean flag, boolean changed)
	{
		Transform transform;
		int param, subparam;
		
		for(int i = 0; i < transcount; i++)
		{
			transform = (Transform)transforms.elementAt(i);
			transform.setFrame(group.image.frame);
			
			if(transform.isApplied())
			{
				param = transform.getParam();
				subparam = transform.getSubParam();
				
				switch(param)
				{
					case SHOW:
						setHidden(AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition()));
						break;
					
					case COLOR:
						color = AuxMath.linearFunctionRGB(transform.getData(), transform.getPosition());
						break;
					
					case X:
						switch(subparam)
						{
							case 1:
								data[0] = AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition());
								changed = true;
								break;
							
							case 2:
								data[2] = AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition());
								changed = true;
								break;
							
							case 3:
								data[4] = AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition());
								changed = true;
								break;
						}
						break;
					
					case Y:
						switch(subparam)
						{
							case 1:
								data[1] = AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition());
								changed = true;
								break;
							
							case 2:
								data[3] = AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition());
								changed = true;
								break;
							
							case 3:
								data[5] = AuxMath.specificFunctionFloat(transform.getData(), transform.getPosition());
								changed = true;
								break;
						}
						break;
				}
			}
		}
		
		if(flag && changed)
		{
			create();
			rescale();
		}
	}
	
	public Object getValue(int param, int subparam)
	{
		if(param == X)
		{
			if(subparam == 1)
			{
				return new Double(data[0]);
			}
			else if(subparam == 2)
			{
				return new Double(data[2]);
			}
			else if(subparam == 3)
			{
				return new Double(data[4]);
			}
		}
		else if(param == Y)
		{
			if(subparam == 1)
			{
				return new Double(data[1]);
			}
			else if(subparam == 2)
			{
				return new Double(data[3]);
			}
			else if(subparam == 3)
			{
				return new Double(data[5]);
			}
		}
		else if(param == FILE)
		{
			return filename;
		}
		
		return null;
	}
	
	public void setValue(Object value, int param, int subparam)
	{
		if(param == X)
		{
			if(subparam == 1)
			{
				data[0] = ((Double)value).doubleValue();
			}
			else if(subparam == 2)
			{
				data[2] = ((Double)value).doubleValue();
			}
			else if(subparam == 3)
			{
				data[4] = ((Double)value).doubleValue();
			}
		}
		else if(param == Y)
		{
			if(subparam == 1)
			{
				data[1] = ((Double)value).doubleValue();
			}
			else if(subparam == 2)
			{
				data[3] = ((Double)value).doubleValue();
			}
			else if(subparam == 3)
			{
				data[5] = ((Double)value).doubleValue();
			}
		}
		else if(param == FILE)
		{
			filename = (String)value;
			texdata = null;
		}
	}
}