package modules.viart;

import javax.microedition.lcdui.*;
import java.util.*;
import java.io.*;
import com.one.vector.*;
import com.one.*;
import com.vmx.*;
import filemanager.ColorScheme;
import filemanager.CommandMenu;
import filemanager.HotKeyListener;
import filemanager.LineEffect;
import filemanager.ListMenu;

public class EditCanvas extends gkcCanvas implements Runnable, CommandListener, HotKeyListener
{
	protected static class AnimationThread implements Runnable
	{
		protected EditCanvas canvas;
		
		protected Thread thread;
		protected Object waiter;
		protected boolean isrunning;
		
		protected VectorImage image;
		protected boolean enabled;
		protected long delay;
		
		public AnimationThread(EditCanvas canvas)
		{
			this.canvas = canvas;
			
			waiter = new Object();
			
			thread = new Thread(this);
			thread.start();
		}
		
		public void start(VectorImage image)
		{
			this.image = image;
			delay = image.getFrameDelay();
			
			enabled = true;
			
			synchronized(waiter)
			{
				waiter.notifyAll();
			}
		}
		
		public void stop()
		{
			enabled = false;
			thread.interrupt();
		}
		
		public boolean isRunning()
		{
			return isrunning;
		}
		
		public void run()
		{
			while(true)
			{
				try
				{
					synchronized(waiter)
					{
						isrunning = false;
						waiter.wait();
					}
					
					isrunning = true;
					
					while(enabled)
					{
						synchronized(image)
						{
							image.nextFrame();
						}
						
						Thread.sleep(delay);
						canvas.startRepaint();
					}
				}
				catch(InterruptedException ie)
				{
				}
			}
		}
	}
	
	protected static class KeyRepeatThread implements Runnable
	{
		protected EditCanvas canvas;
		
		protected Thread thread;
		protected Object waiter;
		protected boolean isrunning;
		
		protected boolean enabled;
		protected int key;
		
		public KeyRepeatThread(EditCanvas canvas)
		{
			this.canvas = canvas;
			
			waiter = new Object();
			
			thread = new Thread(this);
			thread.start();
		}
		
		public void start(int key)
		{
			if(isrunning)
			{
				return;
			}
			
			this.key = key;
			
			enabled = true;
			
			synchronized(waiter)
			{
				waiter.notifyAll();
			}
		}
		
		public void stop()
		{
			enabled = false;
			thread.interrupt();
		}
		
		public boolean isRunning()
		{
			return isrunning;
		}
		
		public void run()
		{
			while(true)
			{
				try
				{
					synchronized(waiter)
					{
						isrunning = false;
						waiter.wait();
					}
					
					isrunning = true;
					Thread.sleep(450);
					
					while(enabled)
					{
						canvas.keyPressed(key);
						Thread.yield();
					}
				}
				catch(InterruptedException ie)
				{
				}
			}
		}
	}
	
	protected static class TransformPacket
	{
		protected VectorElement element;
		protected Vector transforms;
		
		public TransformPacket(VectorElement element)
		{
			this.element = element;
			transforms = new Vector();
		}
		
		public void addTransform(int param, int subparam)
		{
			ArrayData data = new ArrayData();
			
			if(param >= VectorElement.START && param <= VectorElement.ANGLE)
			{
				data.type = ArrayData.INTEGER;
				data.inta = ((Integer)element.getValue(param, subparam)).intValue();
			}
			else
			{
				data.type = ArrayData.LINEAR;
				data.vala = ((Double)element.getValue(param, subparam)).doubleValue();
			}
			
			transforms.addElement(new Transform(data, param, subparam, 0, 0, Transform.NORMAL));
		}
		
		public void savePacket(int startframe, int endframe)
		{
			boolean swap = endframe < startframe;
			
			if(swap)
			{
				startframe ^= endframe;
				endframe ^= startframe;
				startframe ^= endframe;
			}
			
			Transform transform;
			int param, subparam;
			ArrayData data;
			
			for(int i = 0; i < transforms.size(); i++)
			{
				transform = (Transform)transforms.elementAt(i);
				param = transform.getParam();
				subparam = transform.getSubParam();
				data = transform.getData();
				
				if(param >= VectorElement.START && param <= VectorElement.ANGLE)
				{
					if(swap)
					{
						data.intb = data.inta;
						data.inta = ((Integer)element.getValue(param, subparam)).intValue();
					}
					else
					{
						data.intb = ((Integer)element.getValue(param, subparam)).intValue();
					}
				}
				else
				{
					if(swap)
					{
						data.valb = data.vala;
						data.vala = ((Double)element.getValue(param, subparam)).doubleValue();
					}
					else
					{
						data.valb = ((Double)element.getValue(param, subparam)).doubleValue();
					}
				}
				
				transform.setBounds(startframe, endframe);
				
				element.addTransform(transform, true);
			}
		}
		
		public VectorElement getElement()
		{
			return element;
		}
	}
	
	public static final int POSITION = 0,
							SIZE = 1,
							START = 2,
							LENGTH = 3,
							ARC_SIZE = 4,
							ROTATION = 5,
							ANGLE = 6,
							THICKNESS = 7;
	
	public static final String[] CODES =
	{
		"XY", "WH", "ST", "LE", "AS", "RO", "AN", "TH"
	};
	
	protected VectorImage image;
	protected int width, height;
	protected int imgwidth, imgheight;
	protected int imgx, imgy;
	protected int cursorx, cursory;
	protected int cursize;
	protected int curthreshold;
	protected boolean skipkey;
	protected boolean scalemode;
	protected boolean framemode;
	protected int lastframe;
	protected int prevframe;
	
	protected int zoomsize;
	protected int zoomcount;
	protected int zoomdelta;
	protected int zoomscale;
	protected int zoomx, zoomy;
	protected int[] zoompoints;
	protected boolean enablezoom;
	
	protected int curx, cury;
	protected int prevx, prevy;
	protected int prevangle;
	protected int pointcount;
	
	protected Group curgroup;
	protected VectorElement curelement;
	protected boolean editmode;
	protected boolean createmode;
	protected int elemtype;
	protected int editstate;
	protected int bindparam;
	
	protected Vector transpackets;
	protected int keyframe;
	
	protected AbstractFont infofont;
	protected String[] info;
	protected int[] infopos;
	
	protected CommandMenu cmenu;
	
	protected Image offscreen;
	protected ExtGraphics offgraphics;
	protected int[] cursorpoints = new int[9];
	
	protected Image viscreen;
	protected Graphics vigraphics;
	
	protected Thread thread;
	protected Object waiter;
	protected boolean ispainting;
	protected boolean isshown;
	protected boolean forcerepaint;
	
	protected KeyRepeatThread repthread;
	protected AnimationThread animthread;
	
	protected Command cmdTools, cmdOK, cmdDrawOptions, cmdObjectBrowser, cmdKeyFrame, cmdGotoStartFrame, cmdGotoEndFrame, cmdImageProperties, cmdMainMenu;
	
	public EditCanvas()
	{
		setFullScreenMode(true);
		
		width = getWidth();
		height = getHeight();
		
		offscreen = Image.createImage(width, height);
		offgraphics = new ExtGraphics(offscreen.getGraphics());
		
		infofont = AbstractFont.getFont(AbstractFont.FACE_SYSTEM, AbstractFont.STYLE_PLAIN, AbstractFont.SIZE_SMALL);
		
		info = new String[4];
		info[0] = "";
		info[1] = "";
		info[2] = "";
		info[3] = "";
		
		infopos = new int[8];
		
		// infopos[0]
		infopos[1] = infofont.getHeight() / 4;
		
		// infopos[2]
		infopos[3] = infofont.getHeight() + infopos[1] * 2;
		
		infopos[4] = infopos[1];
		infopos[5] = infopos[1];
		
		infopos[6] = infopos[1];
		infopos[7] = infopos[3];
		
		//curthreshold = (width + height) / 40;
		curthreshold = Math.max(width, height) / 25;
		cursize = curthreshold;
		
		//cursorx = width / 2;
		//cursory = height / 2;
		
		cursorx = curthreshold;
		cursory = curthreshold;
		
		transpackets = new Vector();
		
		cmenu = new CommandMenu(getRenderer(), this, width, height, AbstractFont.SIZE_SMALL, true, false, true, true, true);
		
		cmdTools = new Command(Locale.getString(this, CustomLocale.TOOLS_CMD), Command.ITEM, 1);
		cmdOK = new Command(Locale.getString(this, CustomLocale.OK_CMD), Command.ITEM, 1);
		cmdDrawOptions = new Command(Locale.getString(this, CustomLocale.DRAW_OPTIONS_CMD), Command.OK, 2);
		cmdObjectBrowser = new Command(Locale.getString(this, CustomLocale.OBJECT_BROWSER_CMD), Command.OK, 3);
		cmdKeyFrame = new Command(Locale.getString(this, CustomLocale.KEYFRAME_CMD), Command.OK, 4);
		cmdGotoStartFrame = new Command(Locale.getString(this, CustomLocale.GOTO_START_FRAME_CMD), Command.OK, 5);
		cmdGotoEndFrame = new Command(Locale.getString(this, CustomLocale.GOTO_END_FRAME_CMD), Command.OK, 6);
		cmdImageProperties = new Command(Locale.getString(this, CustomLocale.IMAGE_PROPERTIES_CMD), Command.OK, 7);
		cmdMainMenu = new Command(Locale.getString(this, CustomLocale.MAIN_MENU_CMD), Command.BACK, 8);
		
		addCommand(cmdTools);
		addCommand(cmdDrawOptions);
		addCommand(cmdObjectBrowser);
		addCommand(cmdKeyFrame);
		addCommand(cmdGotoStartFrame);
		addCommand(cmdGotoEndFrame);
		addCommand(cmdImageProperties);
		addCommand(cmdMainMenu);
		
		setCommandListener(this);
		
		scalemode = false;
		
		waiter = new Object();
		
		thread = new Thread(this);
		thread.start();
		
		repthread = new KeyRepeatThread(this);
		animthread = new AnimationThread(this);
	}
	
	public void setZoomMode(boolean flag)
	{
		enablezoom = flag;
		
		if(enablezoom)
		{
			zoomsize = infofont.getHeight() * 2;
			zoomcount = cursize;
			
			if((zoomcount & 1) == 0)
			{
				zoomcount++;
			}
			
			zoomscale = (zoomsize + zoomcount - 1) / zoomcount;
			zoomsize = zoomscale * zoomcount;
			zoomdelta = (zoomcount - 1) / 2;
			
			zoomx = width - zoomscale * zoomcount - infopos[1];
			zoomy = infopos[1];
			
			zoompoints = new int[zoomcount * zoomcount];
		}
		else
		{
			zoomsize = -infopos[1];
			zoompoints = null;
		}
	}
	
	public void addCommand(Command c)
	{
		cmenu.addCommand(c);
	}
	
	public void removeCommand(Command c)
	{
		cmenu.removeCommand(c);
	}
	
	public void removeAllCommands()
	{
		cmenu.removeAllCommands();
	}
	
	public void setCommandListener(CommandListener cl)
	{
		cmenu.setCommandListener(cl);
	}
	
	public void writeWorkspaceState(DataOutputStream dos) throws IOException
	{
		dos.writeInt(image.currentFrame());
		
		dos.writeInt(cursorx);
		dos.writeInt(cursory);
		
		dos.writeInt(imgx);
		dos.writeInt(imgy);
	}
	
	public void readWorkspaceState(DataInputStream dis) throws IOException
	{
		image.gotoFrame(dis.readInt());
		
		cursorx = dis.readInt();
		cursory = dis.readInt();
		
		imgx = dis.readInt();
		imgy = dis.readInt();
	}
	
	public void setCurrentImage(VectorImage vi)
	{
		if(vi != null)
		{
			image = vi;
		}
		else
		{
			image = new VectorImage();
		}
		
		imgwidth = image.getNativeWidth();
		imgheight = image.getNativeHeight();
		imgx = 0;
		imgy = 0;
		cursorx = curthreshold;
		cursory = curthreshold;
		keyframe = 0;
		
		setScaleMode(true);
		setEditMode(false, false);
		setCurrentGroup(null);
	}
	
	public VectorImage getCurrentImage()
	{
		return image;
	}
	
	public Image getRenderImage()
	{
		return viscreen;
	}
	
	public void setScaleMode(boolean flag)
	{
		scalemode = flag;
		
		if(scalemode)
		{
			image.scaleToFit(width - curthreshold * 2, height - curthreshold * 2);
		}
		else
		{
			image.scale(-1, -1);
		}
		
		double ax = (double)(cursorx - imgx) / (double)imgwidth;
		double ay = (double)(cursory - imgy) / (double)imgheight;
		
		imgwidth = image.getWidth();
		imgheight = image.getHeight();
		
		if(scalemode)
		{
			imgx = (width - imgwidth) / 2;
			imgy = (height - imgheight) / 2;
			
			cursorx = imgx + (int)(ax * imgwidth);
			cursory = imgy + (int)(ay * imgheight);
			
			if(cursorx <= curthreshold)
			{
				cursorx = curthreshold;
			}
			else if(cursorx >= width - curthreshold)
			{
				cursorx = width - curthreshold - 1;
			}
			
			if(cursory <= curthreshold)
			{
				cursory = curthreshold;
			}
			else if(cursory >= height - curthreshold)
			{
				cursory = height - curthreshold - 1;
			}
		}
		else
		{
			cursorx = width / 2;
			cursory = height / 2;
			
			imgx = cursorx - (int)(ax * imgwidth);
			imgy = cursory - (int)(ay * imgheight);
		}
		
		System.gc();
		
		try
		{
			viscreen = Image.createImage(imgwidth, imgheight);
			vigraphics = viscreen.getGraphics();
			
			forcerepaint = true;
		}
		catch(OutOfMemoryError oome)
		{
			viscreen = null;
			vigraphics = null;
		}
		
		if(editmode && editstate != 0)
		{
			editstate++;
			prevState();
		}
		
		startRepaint();
	}
	
	public void setEditMode(boolean edit, boolean create)
	{
		editmode = edit;
		createmode = create;
		
		if(editmode)
		{
			removeCommand(cmdTools);
			addCommand(cmdOK);
			
			if(createmode)
			{
				setInitialInfo();
			}
			else
			{
				setTransformPacket();
			}
		}
		else
		{
			removeCommand(cmdOK);
			addCommand(cmdTools);
			
			info[2] = "";
			info[3] = "";
		}
	}
	
	public void setCurrentGroup(Group grp)
	{
		if(grp != null)
		{
			curgroup = grp;
		}
		else
		{
			curgroup = null;
			
			Enumeration groups = image.listGroups();
			
			while(groups.hasMoreElements())
			{
				curgroup = (Group)groups.nextElement();
			}
		}
	}
	
	public void setCurrentElement(VectorElement ve)
	{
		if(ve != null)
		{
			setEditMode(true, false);
			
			curelement = ve;
			elemtype = VectorElement.elementType(curelement);
			
			if(elemtype == VectorElement.POLYLINE ||
			   elemtype == VectorElement.BEZIER_CURVE)
			{
				pointcount = ((Integer)curelement.getValue(VectorElement.COUNT, -1)).intValue();
			}
			
			editstate = 0;
			
			info[2] = curelement.getName();
			info[3] = "";
		}
		else
		{
			setEditMode(false, false);
		}
		
		startRepaint();
	}
	
	public void addNewElement()
	{
		if(curgroup == null)
		{
			curgroup = new Group();
			image.addGroup(curgroup);
		}
		
		curelement = VectorElement.getInstance(elemtype);
		curelement.create();
		curgroup.addElement(curelement);
		
		editstate = 1;
		
		if(elemtype == VectorElement.LINE ||
		   elemtype == VectorElement.THICK_LINE)
		{
			bindparam = 2;
		}
		else if(elemtype == VectorElement.TRIANGLE ||
		        elemtype == VectorElement.POLYLINE ||
		        elemtype == VectorElement.BEZIER_CURVE ||
		        elemtype == VectorElement.THICK_TRIANGLE ||
		        elemtype == VectorElement.THICK_POLYLINE ||
		        elemtype == VectorElement.THICK_BEZIER_CURVE)
		{
			bindparam = 3;
		}
		else
		{
			bindparam = 1;
		}
		
		if(elemtype == VectorElement.POLYLINE ||
		   elemtype == VectorElement.BEZIER_CURVE ||
		   elemtype == VectorElement.THICK_POLYLINE ||
		   elemtype == VectorElement.THICK_BEZIER_CURVE)
		{
			pointcount = 3;
		}
		
		if(elemtype == VectorElement.ARC)
		{
			curelement.setValue(new Integer(360), VectorElement.LENGTH, -1);
		}
		
		if(elemtype == VectorElement.POLYGON ||
		   elemtype == VectorElement.THICK_POLYGON)
		{
			curelement.setValue(new Integer(DrawOptions.polyCount), VectorElement.POLY_COUNT, -1);
		}
		
		if(elemtype == VectorElement.BEZIER_CURVE ||
		   elemtype == VectorElement.THICK_BEZIER_CURVE ||
		   elemtype == VectorElement.GRADIENT_RECT ||
		   elemtype == VectorElement.GRADIENT_CIRCLE)
		{
			curelement.setValue(new Integer(DrawOptions.quality), VectorElement.QUALITY, -1);
		}
		
		if(elemtype == VectorElement.GRADIENT_RECT ||
		   elemtype == VectorElement.GRADIENT_CIRCLE)
		{
			curelement.setValue(new Integer(DrawOptions.primaryColor), VectorElement.COLOR, 0);
			curelement.setValue(new Integer(DrawOptions.secondaryColor), VectorElement.COLOR, 1);
		}
		else if(elemtype >= VectorElement.LINE_ARRAY &&
		        elemtype <= VectorElement.POLYGON_ARRAY)
		{
			curelement.setValue(new Integer(DrawOptions.primaryColor), VectorElement.INT_A, 0);
			curelement.setValue(new Integer(DrawOptions.secondaryColor), VectorElement.INT_B, 0);
		}
		else
		{
			curelement.setColor(DrawOptions.primaryColor);
		}
		
		curelement.setDotted(DrawOptions.dotted);
		curelement.setFill(DrawOptions.fill);
		
		updateElement();
	}
	
	public void showNotify()
	{
		isshown = true;
		skipkey = true;
		forcerepaint = true;
		
		startRepaint();
	}
	
	public void hideNotify()
	{
		isshown = false;
		
		repthread.stop();
		animthread.stop();
	}
	
	public void hotKeyAction(int keyCode)
	{
		if(keyCode == KEY_STAR)
		{
			VIArt.showMemoryMonitor(this);
		}
	}
	
	public void keyPressed(int keyCode)
	{
		if(cmenu.keyPressed(keyCode))
		{
			startRepaint();
			return;
		}
		
		keyCode = translateKey(keyCode);
		
		if(keyCode == KEY_FIRE)
		{
			if(editmode)
			{
				nextState(true);
			}
		}
		else if(keyCode == KEY_NUM1)
		{
			if(editmode)
			{
				prevState();
			}
			else
			{
				image.prevFrame();
				repthread.start(keyCode);
				startRepaint();
			}
		}
		else if(keyCode == KEY_NUM3)
		{
			if(editmode)
			{
				nextState(false);
			}
			else
			{
				image.nextFrame();
				repthread.start(keyCode);
				startRepaint();
			}
		}
		else if(keyCode == KEY_NUM7)
		{
			if(editmode)
			{
				setCurrentElement(curgroup.getPreviousElement(curelement));
			}
			else
			{
				image.gotoFrame(image.currentFrame() - 10);
				repthread.start(keyCode);
				startRepaint();
			}
		}
		else if(keyCode == KEY_NUM9)
		{
			if(editmode)
			{
				setCurrentElement(curgroup.getNextElement(curelement));
			}
			else
			{
				image.gotoFrame(image.currentFrame() + 10);
				repthread.start(keyCode);
				startRepaint();
			}
		}
		else if(keyCode == KEY_NUM0)
		{
			setScaleMode(!scalemode);
		}
		else if(keyCode == KEY_STAR)
		{
			if(animthread.isRunning())
			{
				animthread.stop();
			}
			else
			{
				animthread.start(image);
			}
		}
		else if(keyCode == KEY_UP)
		{
			if(cursory > curthreshold)
			{
				cursory--;
			}
			else
			{
				imgy++;
			}
			
			repthread.start(keyCode);
			
			if(editmode)
			{
				updateElement();
			}
			else
			{
				startRepaint();
			}
		}
		else if(keyCode == KEY_DOWN)
		{
			if(cursory < height - curthreshold - 1)
			{
				cursory++;
			}
			else
			{
				imgy--;
			}
			
			repthread.start(keyCode);
			
			if(editmode)
			{
				updateElement();
			}
			else
			{
				startRepaint();
			}
		}
		else if(keyCode == KEY_LEFT)
		{
			if(cursorx > curthreshold)
			{
				cursorx--;
			}
			else
			{
				imgx++;
			}
			
			repthread.start(keyCode);
			
			if(editmode)
			{
				updateElement();
			}
			else
			{
				startRepaint();
			}
		}
		else if(keyCode == KEY_RIGHT)
		{
			if(cursorx < width - curthreshold - 1)
			{
				cursorx++;
			}
			else
			{
				imgx--;
			}
			
			repthread.start(keyCode);
			
			if(editmode)
			{
				updateElement();
			}
			else
			{
				startRepaint();
			}
		}
	}
	
	public void keyReleased(int keyCode)
	{
		repthread.stop();
		
		if(cmenu.keyReleased(keyCode))
		{
			startRepaint();
		}
	}
	
	public void keyRepeated(int keyCode)
	{
		if(cmenu.isInMenu())
		{
			keyPressed(keyCode);
		}
	}
	
	public void startRepaint()
	{
		synchronized(waiter)
		{
			if(!ispainting)
			{
				waiter.notifyAll();
			}
		}
	}
	
	public void waitForRepaint()
	{
		synchronized(waiter)
		{
			if(ispainting)
			{
				try
				{
					waiter.wait();
				}
				catch(InterruptedException ie)
				{
				}
			}
		}
	}
	
	public void paint(ExtGraphics g)
	{
		synchronized(offscreen)
		{
			g.drawImage(offscreen, 0, 0, Graphics.LEFT | Graphics.TOP);
		}
	}
	
	public void run()
	{
		try
		{
			while(true)
			{
				synchronized(waiter)
				{
					ispainting = false;
					
					waiter.notifyAll();
					waiter.wait();
					
					ispainting = true;
				}
				
				synchronized(image)
				{
					if(forcerepaint)
					{
						image.update();
					}
					
					if(vigraphics != null && (image.currentFrame() != prevframe || forcerepaint))
					{
						image.paint(vigraphics, 0, 0);
						
						prevframe = image.currentFrame();
						forcerepaint = false;
					}
				}
				
				synchronized(offscreen)
				{
					offgraphics.setClip(0, 0, width, height);
					offgraphics.setColor(ColorScheme.colors[ColorScheme.drap]);
					offgraphics.fillRect(0, 0, width, height);
					
					if(vigraphics != null)
					{
						offgraphics.drawImage(viscreen, imgx, imgy, Graphics.LEFT | Graphics.TOP);
					}
					else
					{
						offgraphics.setColor(ColorScheme.colors[ColorScheme.drap] ^ 0xFFFFFF);
						
						synchronized(image)
						{
							image.paint(offgraphics.getGraphics(), imgx, imgy);
						}
					}
					
					int border;
					
					if(image.getUseColor() && image.getUseBack())
					{
						border = image.getBackColor() ^ 0xFFFFFF;
					}
					else
					{
						border = ColorScheme.colors[ColorScheme.ltborder];
					}
					
					offgraphics.setColor(border);
					offgraphics.drawRect(imgx - 1, imgy - 1, imgwidth + 1, imgheight + 1);
					
					try
					{
						offscreen.getRGB(cursorpoints, 0, 3, cursorx - 1, cursory - 1, 3, 3);
						
						if(enablezoom)
						{
							offscreen.getRGB(zoompoints, 0, zoomcount, cursorx - zoomdelta, cursory - zoomdelta, zoomcount, zoomcount);
						}
					}
					catch(Exception e)
					{
					}
						
					offgraphics.setColor(AuxMath.averageColorNoAlpha(cursorpoints) ^ 0xFFFFFF);
					offgraphics.drawLine(cursorx, cursory - cursize, cursorx, cursory - 2);
					offgraphics.drawLine(cursorx, cursory + 2, cursorx, cursory + cursize);
					offgraphics.drawLine(cursorx - cursize, cursory, cursorx - 2, cursory);
					offgraphics.drawLine(cursorx + 2, cursory, cursorx + cursize, cursory);
					
					int i;
					
					for(i = 0; i < cursorpoints.length; i++)
					{
						cursorpoints[i] ^= 0xC0C0C0;
					}
					
					offgraphics.drawRGB(cursorpoints, 0, 3, cursorx - 1, cursory - 1, 3, 3, false);
					
					if(enablezoom)
					{
						LineEffect.drawScaledRGB(offgraphics, zoompoints, zoomx, zoomy, zoomcount, zoomcount, zoomscale);
						offgraphics.setColor(border);
						offgraphics.drawRect(zoomx, zoomy, zoomsize - 1, zoomsize - 1);
					}
					
					info[0] = Integer.toString(cursorx - imgx) + ", " + Integer.toString(cursory - imgy);
					infopos[0] = width - zoomsize - infofont.stringWidth(info[0]) - infopos[1] * 2;
					
					info[1] = Integer.toString(image.currentFrame());
					infopos[2] = width - zoomsize - infofont.stringWidth(info[1]) - infopos[1] * 2;
					
					offgraphics.setFont(infofont);
					
					for(i = 0; i < info.length; i++)
					{
						offgraphics.setColor(ColorScheme.colors[ColorScheme.ltborder]);
						LineEffect.drawTextOutline(offgraphics, info[i], infopos[i * 2], infopos[i * 2 + 1]);
						
						offgraphics.setColor(ColorScheme.colors[ColorScheme.dkborder]);
						offgraphics.drawString(info[i], infopos[i * 2], infopos[i * 2 + 1], Graphics.LEFT | Graphics.TOP);
					}
					
					cmenu.paint(offgraphics);
				}
				
				if(isshown)
				{
					repaint();
				}
			}
		}
		catch(InterruptedException ie)
		{
		}
	}
	
	public void commandAction(Command c, Displayable dp)
	{
		if(dp instanceof Renderer)
		{
			PaintableObject po = ((Renderer)dp).getCurrent();
			
			if(po == this)
			{
				if(c == cmdTools)
				{
					VIArt.showToolList(this, true, false, false, elemtype);
				}
				else if(c == cmdOK)
				{
					setEditMode(false, false);
				}
				else if(c == cmdDrawOptions)
				{
					for(int i = 0; i < cursorpoints.length; i++)
					{
						cursorpoints[i] ^= 0xC0C0C0;
					}
					
					DrawOptions.exactCurColor = cursorpoints[cursorpoints.length / 2];
					DrawOptions.averageCurColor = AuxMath.averageColor(cursorpoints);
					
					DrawOptions.cursorX = (double)(cursorx - imgx) / (double)imgwidth;
					DrawOptions.cursorY = (double)(cursory - imgy) / (double)imgheight;
					
					VIArt.showDrawOptions(true);
				}
				else if(c == cmdObjectBrowser)
				{
					VIArt.showObjectBrowser(ObjectBrowser.VIEW_GROUPS);
				}
				else if(c == cmdKeyFrame)
				{
					if(image.currentFrame() != keyframe)
					{
						for(int i = 0; i < transpackets.size(); i++)
						{
							((TransformPacket)transpackets.elementAt(i)).savePacket(keyframe, image.currentFrame());
						}
						
						image.nextFrame();
						keyframe = image.currentFrame();
					}
					
					transpackets.removeAllElements();
					
					if(editmode && !createmode)
					{
						setTransformPacket();
					}
				}
				else if(c == cmdGotoStartFrame)
				{
					image.gotoFrame(0);
					startRepaint();
				}
				else if(c == cmdGotoEndFrame)
				{
					image.gotoFrame(image.getMaxFrame());
					startRepaint();
				}
				else if(c == cmdImageProperties)
				{
					VIArt.showImageProperties(image);
				}
				else if(c == cmdMainMenu)
				{
					VIArt.showMainMenu();
				}
			}
			else if(po instanceof ListMenu)
			{
				VIArt.showEdit(false);
				
				if(c.getCommandType() == Command.OK)
				{
					elemtype = ((ListMenu)po).getSelectedIndex();
					editstate = 0;
					
					setEditMode(true, true);
					startRepaint();
				}
			}
		}
	}
	
	public void moveCursor(int x, int y)
	{
		int cx = x + imgx;
		int cy = y + imgy;
		
		if(cx <= curthreshold)
		{
			imgx = curthreshold - x;
		}
		else if(cx >= width - curthreshold)
		{
			imgx = width - curthreshold - x - 1;
		}
		
		if(cy <= curthreshold)
		{
			imgy = curthreshold - y;
		}
		else if(cy >= height - curthreshold)
		{
			imgy = height - curthreshold - y - 1;
		}
		
		cursorx = x + imgx;
		cursory = y + imgy;
		
		startRepaint();
	}
	
	protected void setInitialInfo()
	{
		info[2] = image.currentElementName(elemtype);
		
		if(elemtype == VectorElement.LINE ||
		   elemtype == VectorElement.TRIANGLE ||
		   elemtype == VectorElement.POLYLINE ||
		   elemtype == VectorElement.BEZIER_CURVE ||
		   elemtype == VectorElement.THICK_LINE ||
		   elemtype == VectorElement.THICK_TRIANGLE ||
		   elemtype == VectorElement.THICK_POLYLINE ||
		   elemtype == VectorElement.THICK_BEZIER_CURVE)
		{
			info[3] = CODES[POSITION] + "1";
		}
		else
		{
			info[3] = CODES[POSITION];
		}
	}
	
	protected void updateElement()
	{
		if(editstate == 0)
		{
			startRepaint();
			return;
		}
		
		if(elemtype == VectorElement.CLIP)
		{
			if(editstate == 1)
			{
				Double ax = new Double(curelement.getInternal(cursorx - imgx, 0));
				Double ay = new Double(curelement.getInternal(cursory - imgy, 1));
				
				curelement.setValue(ax, VectorElement.X, -1);
				curelement.setValue(ay, VectorElement.Y, -1);
			}
			else if(editstate == 2)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Double ax = new Double(curelement.getInternal(Math.min(curx, prevx), 0));
				Double ay = new Double(curelement.getInternal(Math.min(cury, prevy), 1));
				Double aw = new Double(curelement.getInternal(Math.abs(curx - prevx), 2));
				Double ah = new Double(curelement.getInternal(Math.abs(cury - prevy), 3));
				
				curelement.setValue(ax, VectorElement.X, -1);
				curelement.setValue(ay, VectorElement.Y, -1);
				curelement.setValue(aw, VectorElement.WIDTH, -1);
				curelement.setValue(ah, VectorElement.HEIGHT, -1);
			}
		}
		else if(elemtype == VectorElement.LINE)
		{
			Double ax = new Double(curelement.getInternal(cursorx - imgx, 0));
			Double ay = new Double(curelement.getInternal(cursory - imgy, 1));
			
			if(editstate == 1)
			{
				curelement.setValue(ax, VectorElement.X, 1);
				curelement.setValue(ay, VectorElement.Y, 1);
				
				if(bindparam == 2)
				{
					curelement.setValue(ax, VectorElement.X, 2);
					curelement.setValue(ay, VectorElement.Y, 2);
				}
			}
			else if(editstate == 2)
			{
				curelement.setValue(ax, VectorElement.X, 2);
				curelement.setValue(ay, VectorElement.Y, 2);
			}
		}
		else if(elemtype == VectorElement.ARC)
		{
			if(editstate == 1)
			{
				Double ax = new Double(curelement.getInternal(cursorx - imgx, 0));
				Double ay = new Double(curelement.getInternal(cursory - imgy, 1));
				
				curelement.setValue(ax, VectorElement.X, -1);
				curelement.setValue(ay, VectorElement.Y, -1);
			}
			else if(editstate == 2)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Double ax = new Double(curelement.getInternal(Math.min(curx, prevx), 0));
				Double ay = new Double(curelement.getInternal(Math.min(cury, prevy), 1));
				Double aw = new Double(curelement.getInternal(Math.abs(curx - prevx), 2));
				Double ah = new Double(curelement.getInternal(Math.abs(cury - prevy), 3));
				
				curelement.setValue(ax, VectorElement.X, -1);
				curelement.setValue(ay, VectorElement.Y, -1);
				curelement.setValue(aw, VectorElement.WIDTH, -1);
				curelement.setValue(ah, VectorElement.HEIGHT, -1);
			}
			else if(editstate == 3)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Integer angle = new Integer(AuxMath.normAngle(AuxMath.toDegrees(AuxMath.atan2(prevy - cury, curx - prevx)) - prevangle));
				
				curelement.setValue(angle, VectorElement.LENGTH, -1);
			}
			else if(editstate == 4)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Integer angle = new Integer(AuxMath.toDegrees(AuxMath.atan2(prevy - cury, curx - prevx)));
				
				curelement.setValue(angle, VectorElement.START, -1);
			}
		}
		else if(elemtype == VectorElement.RECT)
		{
			if(editstate == 1)
			{
				Double ax = new Double(curelement.getInternal(cursorx - imgx, 0));
				Double ay = new Double(curelement.getInternal(cursory - imgy, 1));
				
				curelement.setValue(ax, VectorElement.X, -1);
				curelement.setValue(ay, VectorElement.Y, -1);
			}
			else if(editstate == 2)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Double ax = new Double(curelement.getInternal(Math.min(curx, prevx), 0));
				Double ay = new Double(curelement.getInternal(Math.min(cury, prevy), 1));
				Double aw = new Double(curelement.getInternal(Math.abs(curx - prevx), 2));
				Double ah = new Double(curelement.getInternal(Math.abs(cury - prevy), 3));
				
				curelement.setValue(ax, VectorElement.X, -1);
				curelement.setValue(ay, VectorElement.Y, -1);
				curelement.setValue(aw, VectorElement.WIDTH, -1);
				curelement.setValue(ah, VectorElement.HEIGHT, -1);
			}
		}
		else if(elemtype == VectorElement.ROUND_RECT)
		{
			if(editstate == 1)
			{
				Double ax = new Double(curelement.getInternal(cursorx - imgx, 0));
				Double ay = new Double(curelement.getInternal(cursory - imgy, 1));
				
				curelement.setValue(ax, VectorElement.X, -1);
				curelement.setValue(ay, VectorElement.Y, -1);
			}
			else if(editstate == 2)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Double ax = new Double(curelement.getInternal(Math.min(curx, prevx), 0));
				Double ay = new Double(curelement.getInternal(Math.min(cury, prevy), 1));
				Double aw = new Double(curelement.getInternal(Math.abs(curx - prevx), 2));
				Double ah = new Double(curelement.getInternal(Math.abs(cury - prevy), 3));
				
				curelement.setValue(ax, VectorElement.X, -1);
				curelement.setValue(ay, VectorElement.Y, -1);
				curelement.setValue(aw, VectorElement.WIDTH, -1);
				curelement.setValue(ah, VectorElement.HEIGHT, -1);
			}
			else if(editstate == 3)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Double aw;
				Double ah;
				
				if(curx > prevx)
				{
					aw = new Double(curelement.getInternal(curx - prevx, 2));
				}
				else
				{
					aw = new Double(0);
				}
				
				if(cury > prevy)
				{
					ah = new Double(curelement.getInternal(cury - prevy, 3));
				}
				else
				{
					ah = new Double(0);
				}
				
				curelement.setValue(aw, VectorElement.ARC_WIDTH, -1);
				curelement.setValue(ah, VectorElement.ARC_HEIGHT, -1);
			}
		}
		else if(elemtype == VectorElement.POINT)
		{
			Double ax = new Double(curelement.getInternal(cursorx - imgx, 0));
			Double ay = new Double(curelement.getInternal(cursory - imgy, 1));
			
			if(editstate == 1)
			{
				curelement.setValue(ax, VectorElement.X, -1);
				curelement.setValue(ay, VectorElement.Y, -1);
			}
		}
		else if(elemtype == VectorElement.TRIANGLE)
		{
			Double ax = new Double(curelement.getInternal(cursorx - imgx, 0));
			Double ay = new Double(curelement.getInternal(cursory - imgy, 1));
			
			if(editstate == 1)
			{
				curelement.setValue(ax, VectorElement.X, 1);
				curelement.setValue(ay, VectorElement.Y, 1);
				
				if(bindparam == 2)
				{
					curelement.setValue(ax, VectorElement.X, 3);
					curelement.setValue(ay, VectorElement.Y, 3);
				}
				else if(bindparam == 3)
				{
					curelement.setValue(ax, VectorElement.X, 2);
					curelement.setValue(ay, VectorElement.Y, 2);
					
					curelement.setValue(ax, VectorElement.X, 3);
					curelement.setValue(ay, VectorElement.Y, 3);
				}
			}
			else if(editstate == 2)
			{
				curelement.setValue(ax, VectorElement.X, 2);
				curelement.setValue(ay, VectorElement.Y, 2);
				
				if(bindparam == 2)
				{
					curelement.setValue(ax, VectorElement.X, 3);
					curelement.setValue(ay, VectorElement.Y, 3);
				}
			}
			else if(editstate == 3)
			{
				curelement.setValue(ax, VectorElement.X, 3);
				curelement.setValue(ay, VectorElement.Y, 3);
			}
		}
		else if(elemtype == VectorElement.POLYLINE)
		{
			Double ax = new Double(curelement.getInternal(cursorx - imgx, 0));
			Double ay = new Double(curelement.getInternal(cursory - imgy, 1));
			
			curelement.setValue(ax, VectorElement.X, editstate);
			curelement.setValue(ay, VectorElement.Y, editstate);
			
			if(bindparam == 2)
			{
				curelement.setValue(ax, VectorElement.X, 3);
				curelement.setValue(ay, VectorElement.Y, 3);
			}
			else if(bindparam == 3)
			{
				curelement.setValue(ax, VectorElement.X, 2);
				curelement.setValue(ay, VectorElement.Y, 2);
				
				curelement.setValue(ax, VectorElement.X, 3);
				curelement.setValue(ay, VectorElement.Y, 3);
			}
		}
		else if(elemtype == VectorElement.POLYGON)
		{
			if(editstate == 1)
			{
				Double ax = new Double(curelement.getInternal(cursorx - imgx, 0));
				Double ay = new Double(curelement.getInternal(cursory - imgy, 1));
				
				curelement.setValue(ax, VectorElement.X, -1);
				curelement.setValue(ay, VectorElement.Y, -1);
			}
			else if(editstate == 2)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Double aw = new Double(curelement.getInternal(Math.abs(curx - prevx) * 2, 2));
				Double ah = new Double(curelement.getInternal(Math.abs(cury - prevy) * 2, 3));
				
				curelement.setValue(aw, VectorElement.WIDTH, -1);
				curelement.setValue(ah, VectorElement.HEIGHT, -1);
			}
			else if(editstate == 3)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Integer angle = new Integer(AuxMath.toDegrees(AuxMath.atan2(prevy - cury, curx - prevx)));
				
				curelement.setValue(angle, VectorElement.ROTATION, -1);
			}
			else if(editstate == 4)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Integer angle = new Integer(AuxMath.toDegrees(AuxMath.atan2(prevy - cury, curx - prevx)));
				
				curelement.setValue(angle, VectorElement.ANGLE, -1);
			}
		}
		else if(elemtype == VectorElement.BEZIER_CURVE)
		{
			Double ax = new Double(curelement.getInternal(cursorx - imgx, 0));
			Double ay = new Double(curelement.getInternal(cursory - imgy, 1));
			
			curelement.setValue(ax, VectorElement.X, editstate);
			curelement.setValue(ay, VectorElement.Y, editstate);
			
			if(bindparam == 2)
			{
				curelement.setValue(ax, VectorElement.X, 3);
				curelement.setValue(ay, VectorElement.Y, 3);
			}
			else if(bindparam == 3)
			{
				curelement.setValue(ax, VectorElement.X, 2);
				curelement.setValue(ay, VectorElement.Y, 2);
				
				curelement.setValue(ax, VectorElement.X, 3);
				curelement.setValue(ay, VectorElement.Y, 3);
			}
		}
		else if(elemtype == VectorElement.THICK_LINE)
		{
			if(editstate == 1)
			{
				Double ax = new Double(curelement.getInternal(cursorx - imgx, 0));
				Double ay = new Double(curelement.getInternal(cursory - imgy, 1));
				
				curelement.setValue(ax, VectorElement.X, 1);
				curelement.setValue(ay, VectorElement.Y, 1);
				
				if(bindparam == 2)
				{
					curelement.setValue(ax, VectorElement.X, 2);
					curelement.setValue(ay, VectorElement.Y, 2);
				}
			}
			else if(editstate == 2)
			{
				Double ax = new Double(curelement.getInternal(cursorx - imgx, 0));
				Double ay = new Double(curelement.getInternal(cursory - imgy, 1));
				
				curelement.setValue(ax, VectorElement.X, 2);
				curelement.setValue(ay, VectorElement.Y, 2);
			}
			else if(editstate == 3)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Double thickness = new Double(curelement.getInternal(AuxMath.hypot(curx - prevx, cury - prevy) * 2, 4));
				
				curelement.setValue(thickness, VectorElement.THICKNESS, -1);
			}
		}
		else if(elemtype == VectorElement.THICK_RECT)
		{
			if(editstate == 1)
			{
				Double ax = new Double(curelement.getInternal(cursorx - imgx, 0));
				Double ay = new Double(curelement.getInternal(cursory - imgy, 1));
				
				curelement.setValue(ax, VectorElement.X, -1);
				curelement.setValue(ay, VectorElement.Y, -1);
			}
			else if(editstate == 2)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Double ax = new Double(curelement.getInternal(Math.min(curx, prevx), 0));
				Double ay = new Double(curelement.getInternal(Math.min(cury, prevy), 1));
				Double aw = new Double(curelement.getInternal(Math.abs(curx - prevx), 2));
				Double ah = new Double(curelement.getInternal(Math.abs(cury - prevy), 3));
				
				curelement.setValue(ax, VectorElement.X, -1);
				curelement.setValue(ay, VectorElement.Y, -1);
				curelement.setValue(aw, VectorElement.WIDTH, -1);
				curelement.setValue(ah, VectorElement.HEIGHT, -1);
			}
			else if(editstate == 3)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Double thickness = new Double(curelement.getInternal(AuxMath.hypot(curx - prevx, cury - prevy) * 2, 4));
				
				curelement.setValue(thickness, VectorElement.THICKNESS, -1);
			}
		}
		else if(elemtype == VectorElement.THICK_TRIANGLE)
		{
			Double ax = new Double(curelement.getInternal(cursorx - imgx, 0));
			Double ay = new Double(curelement.getInternal(cursory - imgy, 1));
			
			if(editstate == 1)
			{
				curelement.setValue(ax, VectorElement.X, 1);
				curelement.setValue(ay, VectorElement.Y, 1);
				
				if(bindparam == 2)
				{
					curelement.setValue(ax, VectorElement.X, 3);
					curelement.setValue(ay, VectorElement.Y, 3);
				}
				else if(bindparam == 3)
				{
					curelement.setValue(ax, VectorElement.X, 2);
					curelement.setValue(ay, VectorElement.Y, 2);
					
					curelement.setValue(ax, VectorElement.X, 3);
					curelement.setValue(ay, VectorElement.Y, 3);
				}
			}
			else if(editstate == 2)
			{
				curelement.setValue(ax, VectorElement.X, 2);
				curelement.setValue(ay, VectorElement.Y, 2);
				
				if(bindparam == 2)
				{
					curelement.setValue(ax, VectorElement.X, 3);
					curelement.setValue(ay, VectorElement.Y, 3);
				}
			}
			else if(editstate == 3)
			{
				curelement.setValue(ax, VectorElement.X, 3);
				curelement.setValue(ay, VectorElement.Y, 3);
			}
			else if(editstate == 4)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Double thickness = new Double(curelement.getInternal(AuxMath.hypot(curx - prevx, cury - prevy) * 2, 4));
				
				curelement.setValue(thickness, VectorElement.THICKNESS, -1);
			}
		}
		else if(elemtype == VectorElement.THICK_POLYLINE)
		{
			if(editstate <= pointcount)
			{
				Double ax = new Double(curelement.getInternal(cursorx - imgx, 0));
				Double ay = new Double(curelement.getInternal(cursory - imgy, 1));
				
				curelement.setValue(ax, VectorElement.X, editstate);
				curelement.setValue(ay, VectorElement.Y, editstate);
				
				if(bindparam == 2)
				{
					curelement.setValue(ax, VectorElement.X, 3);
					curelement.setValue(ay, VectorElement.Y, 3);
				}
				else if(bindparam == 3)
				{
					curelement.setValue(ax, VectorElement.X, 2);
					curelement.setValue(ay, VectorElement.Y, 2);
					
					curelement.setValue(ax, VectorElement.X, 3);
					curelement.setValue(ay, VectorElement.Y, 3);
				}
			}
			else
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Double thickness = new Double(curelement.getInternal(AuxMath.hypot(curx - prevx, cury - prevy) * 2, 4));
				
				curelement.setValue(thickness, VectorElement.THICKNESS, -1);
			}
		}
		else if(elemtype == VectorElement.THICK_POLYGON)
		{
			if(editstate == 1)
			{
				Double ax = new Double(curelement.getInternal(cursorx - imgx, 0));
				Double ay = new Double(curelement.getInternal(cursory - imgy, 1));
				
				curelement.setValue(ax, VectorElement.X, -1);
				curelement.setValue(ay, VectorElement.Y, -1);
			}
			else if(editstate == 2)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Double aw = new Double(curelement.getInternal(Math.abs(curx - prevx) * 2, 2));
				Double ah = new Double(curelement.getInternal(Math.abs(cury - prevy) * 2, 3));
				
				curelement.setValue(aw, VectorElement.WIDTH, -1);
				curelement.setValue(ah, VectorElement.HEIGHT, -1);
			}
			else if(editstate == 3)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Integer angle = new Integer(AuxMath.toDegrees(AuxMath.atan2(prevy - cury, curx - prevx)));
				
				curelement.setValue(angle, VectorElement.ROTATION, -1);
			}
			else if(editstate == 4)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Integer angle = new Integer(AuxMath.toDegrees(AuxMath.atan2(prevy - cury, curx - prevx)));
				
				curelement.setValue(angle, VectorElement.ANGLE, -1);
			}
			else if(editstate == 5)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Double thickness = new Double(curelement.getInternal(AuxMath.hypot(curx - prevx, cury - prevy) * 2, 4));
				
				curelement.setValue(thickness, VectorElement.THICKNESS, -1);
			}
		}
		else if(elemtype == VectorElement.THICK_BEZIER_CURVE)
		{
			if(editstate <= pointcount)
			{
				Double ax = new Double(curelement.getInternal(cursorx - imgx, 0));
				Double ay = new Double(curelement.getInternal(cursory - imgy, 1));
				
				curelement.setValue(ax, VectorElement.X, editstate);
				curelement.setValue(ay, VectorElement.Y, editstate);
				
				if(bindparam == 2)
				{
					curelement.setValue(ax, VectorElement.X, 3);
					curelement.setValue(ay, VectorElement.Y, 3);
				}
				else if(bindparam == 3)
				{
					curelement.setValue(ax, VectorElement.X, 2);
					curelement.setValue(ay, VectorElement.Y, 2);
					
					curelement.setValue(ax, VectorElement.X, 3);
					curelement.setValue(ay, VectorElement.Y, 3);
				}
			}
			else
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Double thickness = new Double(curelement.getInternal(AuxMath.hypot(curx - prevx, cury - prevy) * 2, 4));
				
				curelement.setValue(thickness, VectorElement.THICKNESS, -1);
			}
		}
		else if(elemtype == VectorElement.GRADIENT_RECT)
		{
			if(editstate == 1)
			{
				Double ax = new Double(curelement.getInternal(cursorx - imgx, 0));
				Double ay = new Double(curelement.getInternal(cursory - imgy, 1));
				
				curelement.setValue(ax, VectorElement.X, -1);
				curelement.setValue(ay, VectorElement.Y, -1);
			}
			else if(editstate == 2)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Double aw = new Double(curelement.getInternal(Math.abs(curx - prevx) * 2, 2));
				Double ah = new Double(curelement.getInternal(Math.abs(cury - prevy) * 2, 3));
				
				curelement.setValue(aw, VectorElement.WIDTH, -1);
				curelement.setValue(ah, VectorElement.HEIGHT, -1);
			}
			else if(editstate == 3)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Integer angle = new Integer(AuxMath.toDegrees(AuxMath.atan2(prevy - cury, curx - prevx)));
				
				curelement.setValue(angle, VectorElement.ANGLE, -1);
			}
		}
		else if(elemtype == VectorElement.GRADIENT_CIRCLE)
		{
			if(editstate == 1)
			{
				Double ax = new Double(curelement.getInternal(cursorx - imgx, 0));
				Double ay = new Double(curelement.getInternal(cursory - imgy, 1));
				
				curelement.setValue(ax, VectorElement.X, -1);
				curelement.setValue(ay, VectorElement.Y, -1);
			}
			else if(editstate == 2)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Double aw = new Double(curelement.getInternal(Math.abs(curx - prevx) * 2, 2));
				Double ah = new Double(curelement.getInternal(Math.abs(cury - prevy) * 2, 3));
				
				curelement.setValue(aw, VectorElement.WIDTH, -1);
				curelement.setValue(ah, VectorElement.HEIGHT, -1);
			}
			else if(editstate == 3)
			{
				curx = cursorx - imgx;
				cury = cursory - imgy;
				
				Integer angle = new Integer(AuxMath.toDegrees(AuxMath.atan2(prevy - cury, curx - prevx)));
				
				curelement.setValue(angle, VectorElement.ANGLE, -1);
			}
		}
		
		synchronized(image)
		{
			curelement.create();
			curelement.rescale();
		}
		
		forcerepaint = true;
		startRepaint();
	}
	
	protected void nextState(boolean allowzero)
	{
		if(editstate == 0)
		{
			if(allowzero)
			{
				if(createmode)
				{
					addNewElement();
					nextState(true);
				}
				else
				{
					setEditMode(false, false);
					startRepaint();
				}
			}
			else
			{
				editstate = 2;
				prevState();
			}
			
			return;
		}
		
		if(elemtype == VectorElement.CLIP)
		{
			if(editstate == 1)
			{
				editstate = 2;
				
				info[3] = CODES[SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2);
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3);
				
				moveCursor(ax, ay);
				
				return;
			}
		}
		else if(elemtype == VectorElement.LINE)
		{
			if(editstate == 1)
			{
				editstate = 2;
				bindparam = 1;
				
				info[3] = CODES[POSITION] + "2";
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 2)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 2)).doubleValue(), 1);
				
				moveCursor(ax, ay);
				
				return;
			}
		}
		else if(elemtype == VectorElement.ARC)
		{
			if(editstate == 1)
			{
				editstate = 2;
				
				info[3] = CODES[SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2);
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3);
				
				moveCursor(ax, ay);
				
				return;
			}
			else if(editstate == 2)
			{
				editstate = 3;
				
				info[3] = CODES[LENGTH];
				
				int rx = curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ry = curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0) + rx;
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1) + ry;
				
				prevangle = ((Integer)curelement.getValue(VectorElement.START, -1)).intValue();
				int angle = prevangle + ((Integer)curelement.getValue(VectorElement.LENGTH, -1)).intValue();
				
				int ax = prevx + (int)(AuxMath.cos(angle) * rx);
				int ay = prevy - (int)(AuxMath.sin(angle) * ry);
				
				moveCursor(ax, ay);
				
				return;
			}
			else if(editstate == 3)
			{
				editstate = 4;
				
				info[3] = CODES[START];
				
				int rx = curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ry = curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				int angle = ((Integer)curelement.getValue(VectorElement.START, -1)).intValue();
				
				int ax = prevx + (int)(AuxMath.cos(angle) * rx);
				int ay = prevy - (int)(AuxMath.sin(angle) * ry);
				
				moveCursor(ax, ay);
				
				return;
			}
		}
		else if(elemtype == VectorElement.RECT)
		{
			if(editstate == 1)
			{
				editstate = 2;
				
				info[3] = CODES[SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2);
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3);
				
				moveCursor(ax, ay);
				
				return;
			}
		}
		else if(elemtype == VectorElement.ROUND_RECT)
		{
			if(editstate == 1)
			{
				editstate = 2;
				
				info[3] = CODES[SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2);
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3);
				
				moveCursor(ax, ay);
				
				return;
			}
			else if(editstate == 2)
			{
				editstate = 3;
				
				info[3] = CODES[ARC_SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.ARC_WIDTH, -1)).doubleValue(), 2);
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.ARC_HEIGHT, -1)).doubleValue(), 3);
				
				moveCursor(ax, ay);
				
				return;
			}
		}
		else if(elemtype == VectorElement.POINT)
		{
		}
		else if(elemtype == VectorElement.TRIANGLE)
		{
			if(editstate == 1)
			{
				editstate = 2;
				
				if(bindparam == 3)
				{
					bindparam = 2;
				}
				
				info[3] = CODES[POSITION] + "2";
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 2)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 2)).doubleValue(), 1);
				
				moveCursor(ax, ay);
				
				return;
			}
			else if(editstate == 2)
			{
				editstate = 3;
				bindparam = 1;
				
				info[3] = CODES[POSITION] + "3";
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 3)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 3)).doubleValue(), 1);
				
				moveCursor(ax, ay);
				
				return;
			}
		}
		else if(elemtype == VectorElement.POLYLINE)
		{
			boolean flag = false;
			
			if(allowzero)
			{
				if(++editstate > pointcount)
				{
					if(curelement.getValue(VectorElement.X, editstate - 1).equals(curelement.getValue(VectorElement.X, editstate - 2)) &&
					   curelement.getValue(VectorElement.Y, editstate - 1).equals(curelement.getValue(VectorElement.Y, editstate - 2)))
					{
						curelement.setValue(new Integer(editstate - 2), VectorElement.COUNT, -1);
						pointcount = editstate - 2;
					}
					else
					{
						curelement.setValue(new Integer(editstate), VectorElement.COUNT, -1);
						pointcount = editstate;
						
						curelement.setValue(curelement.getValue(VectorElement.X, editstate - 1), VectorElement.X, editstate);
						curelement.setValue(curelement.getValue(VectorElement.Y, editstate - 1), VectorElement.Y, editstate);
						
						flag = true;
					}
				}
				else
				{
					flag = true;
				}
			}
			else if(editstate < pointcount)
			{
				editstate++;
				flag = true;
			}
			else
			{
				return;
			}
			
			if(flag)
			{
				if(bindparam == 3)
				{
					bindparam = 2;
				}
				else if(bindparam == 2)
				{
					bindparam = 1;
				}
				
				info[3] = CODES[POSITION] + Integer.toString(editstate);
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, editstate)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, editstate)).doubleValue(), 1);
				
				moveCursor(ax, ay);
				
				return;
			}
		}
		else if(elemtype == VectorElement.POLYGON)
		{
			if(editstate == 1)
			{
				editstate = 2;
				
				info[3] = CODES[SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				moveCursor(ax, ay);
				
				return;
			}
			else if(editstate == 2)
			{
				editstate = 3;
				
				info[3] = CODES[ROTATION];
				
				int rx = curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ry = curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int angle = ((Integer)curelement.getValue(VectorElement.ROTATION, -1)).intValue();
				
				int ax = prevx + (int)(AuxMath.cos(angle) * rx);
				int ay = prevy - (int)(AuxMath.sin(angle) * ry);
				
				moveCursor(ax, ay);
				
				return;
			}
			else if(editstate == 3)
			{
				editstate = 4;
				
				info[3] = CODES[ANGLE];
				
				int rx = curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ry = curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				int angle = ((Integer)curelement.getValue(VectorElement.ANGLE, -1)).intValue();
				
				int ax = prevx + (int)(AuxMath.cos(angle) * rx);
				int ay = prevy - (int)(AuxMath.sin(angle) * ry);
				
				moveCursor(ax, ay);
				
				return;
			}
		}
		else if(elemtype == VectorElement.BEZIER_CURVE)
		{
			boolean flag = false;
			
			if(allowzero)
			{
				if(++editstate > pointcount)
				{
					if(curelement.getValue(VectorElement.X, editstate - 1).equals(curelement.getValue(VectorElement.X, editstate - 2)) &&
					   curelement.getValue(VectorElement.Y, editstate - 1).equals(curelement.getValue(VectorElement.Y, editstate - 2)))
					{
						curelement.setValue(new Integer(editstate - 2), VectorElement.COUNT, -1);
						pointcount = editstate - 2;
					}
					else
					{
						curelement.setValue(new Integer(editstate), VectorElement.COUNT, -1);
						pointcount = editstate;
						
						curelement.setValue(curelement.getValue(VectorElement.X, editstate - 1), VectorElement.X, editstate);
						curelement.setValue(curelement.getValue(VectorElement.Y, editstate - 1), VectorElement.Y, editstate);
						
						flag = true;
					}
				}
				else
				{
					flag = true;
				}
			}
			else if(editstate < pointcount)
			{
				editstate++;
				flag = true;
			}
			else
			{
				return;
			}
			
			if(flag)
			{
				if(bindparam == 3)
				{
					bindparam = 2;
				}
				else if(bindparam == 2)
				{
					bindparam = 1;
				}
				
				info[3] = CODES[POSITION] + Integer.toString(editstate);
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, editstate)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, editstate)).doubleValue(), 1);
				
				moveCursor(ax, ay);
				
				return;
			}
		}
		else if(elemtype == VectorElement.THICK_LINE)
		{
			if(editstate == 1)
			{
				editstate = 2;
				bindparam = 1;
				
				info[3] = CODES[POSITION] + "2";
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 2)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 2)).doubleValue(), 1);
				
				moveCursor(ax, ay);
				
				return;
			}
			else if(editstate == 2)
			{
				editstate = 3;
				
				info[3] = CODES[THICKNESS];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 2)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 2)).doubleValue(), 1);
				
				prevx = ax;
				prevy = ay;
				
				ax += curelement.getScaled(((Double)curelement.getValue(VectorElement.THICKNESS, -1)).doubleValue(), 4) / 2;
				
				moveCursor(ax, ay);
				
				return;
			}
		}
		else if(elemtype == VectorElement.THICK_RECT)
		{
			if(editstate == 1)
			{
				editstate = 2;
				
				info[3] = CODES[SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2);
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3);
				
				moveCursor(ax, ay);
				
				return;
			}
			else if(editstate == 2)
			{
				editstate = 3;
				
				info[3] = CODES[THICKNESS];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				prevx = ax;
				prevy = ay;
				
				ax += curelement.getScaled(((Double)curelement.getValue(VectorElement.THICKNESS, -1)).doubleValue(), 4) / 2;
				
				moveCursor(ax, ay);
				
				return;
			}
		}
		else if(elemtype == VectorElement.THICK_TRIANGLE)
		{
			if(editstate == 1)
			{
				editstate = 2;
				
				if(bindparam == 3)
				{
					bindparam = 2;
				}
				
				info[3] = CODES[POSITION] + "2";
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 2)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 2)).doubleValue(), 1);
				
				moveCursor(ax, ay);
				
				return;
			}
			else if(editstate == 2)
			{
				editstate = 3;
				bindparam = 1;
				
				info[3] = CODES[POSITION] + "3";
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 3)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 3)).doubleValue(), 1);
				
				moveCursor(ax, ay);
				
				return;
			}
			else if(editstate == 3)
			{
				editstate = 4;
				
				info[3] = CODES[THICKNESS];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 3)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 3)).doubleValue(), 1);
				
				prevx = ax;
				prevy = ay;
				
				ax += curelement.getScaled(((Double)curelement.getValue(VectorElement.THICKNESS, -1)).doubleValue(), 4) / 2;
				
				moveCursor(ax, ay);
				
				return;
			}
		}
		else if(elemtype == VectorElement.THICK_POLYLINE)
		{
			boolean flag = false;
			
			if(allowzero)
			{
				if(editstate <= pointcount)
				{
					if(++editstate > pointcount)
					{
						if(curelement.getValue(VectorElement.X, editstate - 1).equals(curelement.getValue(VectorElement.X, editstate - 2)) &&
						   curelement.getValue(VectorElement.Y, editstate - 1).equals(curelement.getValue(VectorElement.Y, editstate - 2)))
						{
							curelement.setValue(new Integer(editstate - 2), VectorElement.COUNT, -1);
							pointcount = editstate - 2;
							
							editstate = pointcount + 1;
							
							info[3] = CODES[THICKNESS];
							
							int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, pointcount)).doubleValue(), 0);
							int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, pointcount)).doubleValue(), 1);
							
							prevx = ax;
							prevy = ay;
							
							ax += curelement.getScaled(((Double)curelement.getValue(VectorElement.THICKNESS, -1)).doubleValue(), 4) / 2;
							
							moveCursor(ax, ay);
							
							return;
						}
						else
						{
							curelement.setValue(new Integer(editstate), VectorElement.COUNT, -1);
							pointcount = editstate;
							
							curelement.setValue(curelement.getValue(VectorElement.X, editstate - 1), VectorElement.X, editstate);
							curelement.setValue(curelement.getValue(VectorElement.Y, editstate - 1), VectorElement.Y, editstate);
							
							flag = true;
						}
					}
					else
					{
						flag = true;
					}
				}
			}
			else if(editstate < pointcount)
			{
				editstate++;
				flag = true;
			}
			else if(editstate == pointcount)
			{
				editstate = pointcount + 1;
				
				info[3] = CODES[THICKNESS];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, pointcount)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, pointcount)).doubleValue(), 1);
				
				prevx = ax;
				prevy = ay;
				
				ax += curelement.getScaled(((Double)curelement.getValue(VectorElement.THICKNESS, -1)).doubleValue(), 4) / 2;
				
				moveCursor(ax, ay);
				
				return;
			}
			else
			{
				return;
			}
			
			if(flag)
			{
				if(bindparam == 3)
				{
					bindparam = 2;
				}
				else if(bindparam == 2)
				{
					bindparam = 1;
				}
				
				info[3] = CODES[POSITION] + Integer.toString(editstate);
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, editstate)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, editstate)).doubleValue(), 1);
				
				moveCursor(ax, ay);
				
				return;
			}
		}
		else if(elemtype == VectorElement.THICK_POLYGON)
		{
			if(editstate == 1)
			{
				editstate = 2;
				
				info[3] = CODES[SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				moveCursor(ax, ay);
				
				return;
			}
			else if(editstate == 2)
			{
				editstate = 3;
				
				info[3] = CODES[ROTATION];
				
				int rx = curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ry = curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int angle = ((Integer)curelement.getValue(VectorElement.ROTATION, -1)).intValue();
				
				int ax = prevx + (int)(AuxMath.cos(angle) * rx);
				int ay = prevy - (int)(AuxMath.sin(angle) * ry);
				
				moveCursor(ax, ay);
				
				return;
			}
			else if(editstate == 3)
			{
				editstate = 4;
				
				info[3] = CODES[ANGLE];
				
				int rx = curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ry = curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				int angle = ((Integer)curelement.getValue(VectorElement.ANGLE, -1)).intValue();
				
				int ax = prevx + (int)(AuxMath.cos(angle) * rx);
				int ay = prevy - (int)(AuxMath.sin(angle) * ry);
				
				moveCursor(ax, ay);
				
				return;
			}
			else if(editstate == 4)
			{
				editstate = 5;
				
				info[3] = CODES[THICKNESS];
				
				int ax = prevx;
				int ay = prevy;
				
				ax += curelement.getScaled(((Double)curelement.getValue(VectorElement.THICKNESS, -1)).doubleValue(), 4) / 2;
				
				moveCursor(ax, ay);
				
				return;
			}
		}
		else if(elemtype == VectorElement.THICK_BEZIER_CURVE)
		{
			boolean flag = false;
			
			if(allowzero)
			{
				if(editstate <= pointcount)
				{
					if(++editstate > pointcount)
					{
						if(curelement.getValue(VectorElement.X, editstate - 1).equals(curelement.getValue(VectorElement.X, editstate - 2)) &&
						   curelement.getValue(VectorElement.Y, editstate - 1).equals(curelement.getValue(VectorElement.Y, editstate - 2)))
						{
							curelement.setValue(new Integer(editstate - 2), VectorElement.COUNT, -1);
							pointcount = editstate - 2;
							
							editstate = pointcount + 1;
							
							info[3] = CODES[THICKNESS];
							
							int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, pointcount)).doubleValue(), 0);
							int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, pointcount)).doubleValue(), 1);
							
							prevx = ax;
							prevy = ay;
							
							ax += curelement.getScaled(((Double)curelement.getValue(VectorElement.THICKNESS, -1)).doubleValue(), 4) / 2;
							
							moveCursor(ax, ay);
							
							return;
						}
						else
						{
							curelement.setValue(new Integer(editstate), VectorElement.COUNT, -1);
							pointcount = editstate;
							
							curelement.setValue(curelement.getValue(VectorElement.X, editstate - 1), VectorElement.X, editstate);
							curelement.setValue(curelement.getValue(VectorElement.Y, editstate - 1), VectorElement.Y, editstate);
							
							flag = true;
						}
					}
					else
					{
						flag = true;
					}
				}
			}
			else if(editstate < pointcount)
			{
				editstate++;
				flag = true;
			}
			else if(editstate == pointcount)
			{
				editstate = pointcount + 1;
				
				info[3] = CODES[THICKNESS];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, pointcount)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, pointcount)).doubleValue(), 1);
				
				prevx = ax;
				prevy = ay;
				
				ax += curelement.getScaled(((Double)curelement.getValue(VectorElement.THICKNESS, -1)).doubleValue(), 4) / 2;
				
				moveCursor(ax, ay);
				
				return;
			}
			else
			{
				return;
			}
			
			if(flag)
			{
				if(bindparam == 3)
				{
					bindparam = 2;
				}
				else if(bindparam == 2)
				{
					bindparam = 1;
				}
				
				info[3] = CODES[POSITION] + Integer.toString(editstate);
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, editstate)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, editstate)).doubleValue(), 1);
				
				moveCursor(ax, ay);
				
				return;
			}
		}
		else if(elemtype == VectorElement.GRADIENT_RECT)
		{
			if(editstate == 1)
			{
				editstate = 2;
				
				info[3] = CODES[SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				moveCursor(ax, ay);
				
				return;
			}
			else if(editstate == 2)
			{
				editstate = 3;
				
				info[3] = CODES[ANGLE];
				
				int r = curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				
				int angle = ((Integer)curelement.getValue(VectorElement.ANGLE, -1)).intValue();
				
				int ax = prevx + (int)(AuxMath.cos(angle) * r);
				int ay = prevy - (int)(AuxMath.sin(angle) * r);
				
				moveCursor(ax, ay);
				
				return;
			}
		}
		else if(elemtype == VectorElement.GRADIENT_CIRCLE)
		{
			if(editstate == 1)
			{
				editstate = 2;
				
				info[3] = CODES[SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				moveCursor(ax, ay);
				
				return;
			}
			else if(editstate == 2)
			{
				editstate = 3;
				
				info[3] = CODES[ANGLE];
				
				int rx = curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ry = curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				int angle = ((Integer)curelement.getValue(VectorElement.ANGLE, -1)).intValue();
				
				int ax = prevx + (int)(AuxMath.cos(angle) * rx);
				int ay = prevy - (int)(AuxMath.sin(angle) * ry);
				
				moveCursor(ax, ay);
				
				return;
			}
		}
		
		if(allowzero)
		{
			if(createmode)
			{
				editstate = 0;
				setInitialInfo();
			}
			else
			{
				setEditMode(false, false);
			}
			
			startRepaint();
		}
	}
	
	protected void prevState()
	{
		if(editstate == 0)
		{
			if(curelement != null)
			{
				elemtype = VectorElement.elementType(curelement);
			}
			else
			{
				return;
			}
		}
		
		if(elemtype == VectorElement.CLIP)
		{
			if(editstate == 0 || editstate == 3)
			{
				editstate = 2;
				
				info[2] = curelement.getName();
				info[3] = CODES[SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2);
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3);
				
				moveCursor(ax, ay);
			}
			else if(editstate == 2)
			{
				editstate = 1;
				
				info[3] = CODES[POSITION];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
		}
		else if(elemtype == VectorElement.LINE)
		{
			if(editstate == 0 || editstate == 3)
			{
				editstate = 2;
				
				info[2] = curelement.getName();
				info[3] = CODES[POSITION] + "2";
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 2)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 2)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
			else if(editstate == 2)
			{
				editstate = 1;
				
				info[3] = CODES[POSITION] + "1";
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 1)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 1)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
		}
		else if(elemtype == VectorElement.ARC)
		{
			if(editstate == 0 || editstate == 5)
			{
				editstate = 4;
				
				info[2] = curelement.getName();
				info[3] = CODES[START];
				
				int rx = curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ry = curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0) + rx;
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1) + ry;
				
				int angle = ((Integer)curelement.getValue(VectorElement.START, -1)).intValue();
				
				int ax = prevx + (int)(AuxMath.cos(angle) * rx);
				int ay = prevy - (int)(AuxMath.sin(angle) * ry);
				
				moveCursor(ax, ay);
			}
			else if(editstate == 4)
			{
				editstate = 3;
				
				info[3] = CODES[LENGTH];
				
				int rx = curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ry = curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				prevangle = ((Integer)curelement.getValue(VectorElement.START, -1)).intValue();
				int angle = prevangle + ((Integer)curelement.getValue(VectorElement.LENGTH, -1)).intValue();
				
				int ax = prevx + (int)(AuxMath.cos(angle) * rx);
				int ay = prevy - (int)(AuxMath.sin(angle) * ry);
				
				moveCursor(ax, ay);
			}
			else if(editstate == 3)
			{
				editstate = 2;
				
				info[3] = CODES[SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2);
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3);
				
				moveCursor(ax, ay);
			}
			else if(editstate == 2)
			{
				editstate = 1;
				
				info[3] = CODES[POSITION];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
		}
		else if(elemtype == VectorElement.RECT)
		{
			if(editstate == 0 || editstate == 3)
			{
				editstate = 2;
				
				info[2] = curelement.getName();
				info[3] = CODES[SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2);
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3);
				
				moveCursor(ax, ay);
			}
			else if(editstate == 2)
			{
				editstate = 1;
				
				info[3] = CODES[POSITION];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
		}
		else if(elemtype == VectorElement.ROUND_RECT)
		{
			if(editstate == 0 || editstate == 4)
			{
				editstate = 3;
				
				info[2] = curelement.getName();
				info[3] = CODES[ARC_SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.ARC_WIDTH, -1)).doubleValue(), 2);
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.ARC_HEIGHT, -1)).doubleValue(), 3);
				
				moveCursor(ax, ay);
			}
			else if(editstate == 3)
			{
				editstate = 2;
				
				info[3] = CODES[SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2);
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3);
				
				moveCursor(ax, ay);
			}
			else if(editstate == 2)
			{
				editstate = 1;
				
				info[3] = CODES[POSITION];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
		}
		else if(elemtype == VectorElement.POINT)
		{
			if(editstate == 0 || editstate == 2)
			{
				editstate = 1;
				
				info[2] = curelement.getName();
				info[3] = CODES[POSITION];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
		}
		else if(elemtype == VectorElement.TRIANGLE)
		{
			if(editstate == 0 || editstate == 4)
			{
				editstate = 3;
				
				info[2] = curelement.getName();
				info[3] = CODES[POSITION] + "3";
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 3)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 3)).doubleValue(), 1);
				
				moveCursor(ax, ay);
				
				return;
			}
			else if(editstate == 3)
			{
				editstate = 2;
				
				info[3] = CODES[POSITION] + "2";
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 2)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 2)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
			else if(editstate == 2)
			{
				editstate = 1;
				
				info[3] = CODES[POSITION] + "1";
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 1)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 1)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
		}
		else if(elemtype == VectorElement.POLYLINE)
		{
			if(editstate == 0 || editstate == pointcount + 1)
			{
				editstate = pointcount;
				
				info[2] = curelement.getName();
				info[3] = CODES[POSITION] + Integer.toString(editstate);
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, editstate)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, editstate)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
			else if(editstate > 1)
			{
				editstate--;
				
				info[3] = CODES[POSITION] + Integer.toString(editstate);
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, editstate)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, editstate)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
		}
		else if(elemtype == VectorElement.POLYGON)
		{
			if(editstate == 0 || editstate == 5)
			{
				editstate = 4;
				
				info[2] = curelement.getName();
				info[3] = CODES[ANGLE];
				
				int rx = curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ry = curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int angle = ((Integer)curelement.getValue(VectorElement.ANGLE, -1)).intValue();
				
				int ax = prevx + (int)(AuxMath.cos(angle) * rx);
				int ay = prevy - (int)(AuxMath.sin(angle) * ry);
				
				moveCursor(ax, ay);
			}
			else if(editstate == 4)
			{
				editstate = 3;
				
				info[3] = CODES[ROTATION];
				
				int rx = curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ry = curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				int angle = ((Integer)curelement.getValue(VectorElement.ROTATION, -1)).intValue();
				
				int ax = prevx + (int)(AuxMath.cos(angle) * rx);
				int ay = prevy - (int)(AuxMath.sin(angle) * ry);
				
				moveCursor(ax, ay);
			}
			else if(editstate == 3)
			{
				editstate = 2;
				
				info[3] = CODES[SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				moveCursor(ax, ay);
			}
			else if(editstate == 2)
			{
				editstate = 1;
				
				info[3] = CODES[POSITION];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
		}
		else if(elemtype == VectorElement.BEZIER_CURVE)
		{
			if(editstate == 0 || editstate == pointcount + 1)
			{
				editstate = pointcount;
				
				info[2] = curelement.getName();
				info[3] = CODES[POSITION] + Integer.toString(editstate);
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, editstate)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, editstate)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
			else if(editstate > 1)
			{
				editstate--;
				
				info[3] = CODES[POSITION] + Integer.toString(editstate);
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, editstate)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, editstate)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
		}
		else if(elemtype == VectorElement.THICK_LINE)
		{
			if(editstate == 0 || editstate == 4)
			{
				editstate = 3;
				
				info[2] = curelement.getName();
				info[3] = CODES[THICKNESS];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 2)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 2)).doubleValue(), 1);
				
				prevx = ax;
				prevy = ay;
				
				ax += curelement.getScaled(((Double)curelement.getValue(VectorElement.THICKNESS, -1)).doubleValue(), 4) / 2;
				
				moveCursor(ax, ay);
			}
			else if(editstate == 3)
			{
				editstate = 2;
				
				info[3] = CODES[POSITION] + "2";
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 2)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 2)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
			else if(editstate == 2)
			{
				editstate = 1;
				
				info[3] = CODES[POSITION] + "1";
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 1)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 1)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
		}
		else if(elemtype == VectorElement.THICK_RECT)
		{
			if(editstate == 0 || editstate == 4)
			{
				editstate = 3;
				
				info[2] = curelement.getName();
				info[3] = CODES[THICKNESS];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				prevx = ax;
				prevy = ay;
				
				ax += curelement.getScaled(((Double)curelement.getValue(VectorElement.THICKNESS, -1)).doubleValue(), 4) / 2;
				
				moveCursor(ax, ay);
			}
			else if(editstate == 3)
			{
				editstate = 2;
				
				info[3] = CODES[SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2);
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3);
				
				moveCursor(ax, ay);
			}
			else if(editstate == 2)
			{
				editstate = 1;
				
				info[3] = CODES[POSITION];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
		}
		else if(elemtype == VectorElement.THICK_TRIANGLE)
		{
			if(editstate == 0 || editstate == 5)
			{
				editstate = 4;
				
				info[2] = curelement.getName();
				info[3] = CODES[THICKNESS];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 3)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 3)).doubleValue(), 1);
				
				prevx = ax;
				prevy = ay;
				
				ax += curelement.getScaled(((Double)curelement.getValue(VectorElement.THICKNESS, -1)).doubleValue(), 4) / 2;
			}
			else if(editstate == 4)
			{
				editstate = 3;
				
				info[3] = CODES[POSITION] + "3";
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 3)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 3)).doubleValue(), 1);
				
				moveCursor(ax, ay);
				
				return;
			}
			else if(editstate == 3)
			{
				editstate = 2;
				
				info[3] = CODES[POSITION] + "2";
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 2)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 2)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
			else if(editstate == 2)
			{
				editstate = 1;
				
				info[3] = CODES[POSITION] + "1";
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, 1)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, 1)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
		}
		else if(elemtype == VectorElement.THICK_POLYLINE)
		{
			if(editstate == 0 || editstate == pointcount + 2)
			{
				editstate = pointcount + 1;
				
				info[2] = curelement.getName();
				info[3] = CODES[THICKNESS];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, pointcount)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, pointcount)).doubleValue(), 1);
				
				prevx = ax;
				prevy = ay;
				
				ax += curelement.getScaled(((Double)curelement.getValue(VectorElement.THICKNESS, -1)).doubleValue(), 4) / 2;
			}
			else if(editstate > 1)
			{
				editstate--;
				
				info[3] = CODES[POSITION] + Integer.toString(editstate);
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, editstate)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, editstate)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
		}
		else if(elemtype == VectorElement.THICK_POLYGON)
		{
			if(editstate == 0 || editstate == 6)
			{
				editstate = 5;
				
				info[2] = curelement.getName();
				info[3] = CODES[THICKNESS];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx;
				int ay = prevy;
				
				ax += curelement.getScaled(((Double)curelement.getValue(VectorElement.THICKNESS, -1)).doubleValue(), 4) / 2;
				
				moveCursor(ax, ay);
			}
			else if(editstate == 5)
			{
				editstate = 4;
				
				info[3] = CODES[ANGLE];
				
				int rx = curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ry = curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				int angle = ((Integer)curelement.getValue(VectorElement.ANGLE, -1)).intValue();
				
				int ax = prevx + (int)(AuxMath.cos(angle) * rx);
				int ay = prevy - (int)(AuxMath.sin(angle) * ry);
				
				moveCursor(ax, ay);
			}
			else if(editstate == 4)
			{
				editstate = 3;
				
				info[3] = CODES[ROTATION];
				
				int rx = curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ry = curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				int angle = ((Integer)curelement.getValue(VectorElement.ROTATION, -1)).intValue();
				
				int ax = prevx + (int)(AuxMath.cos(angle) * rx);
				int ay = prevy - (int)(AuxMath.sin(angle) * ry);
				
				moveCursor(ax, ay);
			}
			else if(editstate == 3)
			{
				editstate = 2;
				
				info[3] = CODES[SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				moveCursor(ax, ay);
			}
			else if(editstate == 2)
			{
				editstate = 1;
				
				info[3] = CODES[POSITION];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
		}
		else if(elemtype == VectorElement.THICK_BEZIER_CURVE)
		{
			if(editstate == 0 || editstate == pointcount + 2)
			{
				editstate = pointcount + 1;
				
				info[2] = curelement.getName();
				info[3] = CODES[THICKNESS];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, pointcount)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, pointcount)).doubleValue(), 1);
				
				prevx = ax;
				prevy = ay;
				
				ax += curelement.getScaled(((Double)curelement.getValue(VectorElement.THICKNESS, -1)).doubleValue(), 4) / 2;
			}
			else if(editstate > 1)
			{
				editstate--;
				
				info[3] = CODES[POSITION] + Integer.toString(editstate);
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, editstate)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, editstate)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
		}
		else if(elemtype == VectorElement.GRADIENT_RECT)
		{
			if(editstate == 0 || editstate == 4)
			{
				editstate = 3;
				
				info[2] = curelement.getName();
				info[3] = CODES[ANGLE];
				
				int rx = curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ry = curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int angle = ((Integer)curelement.getValue(VectorElement.ANGLE, -1)).intValue();
				
				int ax = prevx + (int)(AuxMath.cos(angle) * rx);
				int ay = prevy - (int)(AuxMath.sin(angle) * ry);
				
				moveCursor(ax, ay);
			}
			else if(editstate == 3)
			{
				editstate = 2;
				
				info[3] = CODES[SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				moveCursor(ax, ay);
			}
			else if(editstate == 2)
			{
				editstate = 1;
				
				info[3] = CODES[POSITION];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
		}
		else if(elemtype == VectorElement.GRADIENT_CIRCLE)
		{
			if(editstate == 0 || editstate == 4)
			{
				editstate = 3;
				
				info[2] = curelement.getName();
				info[3] = CODES[ANGLE];
				
				int rx = curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ry = curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int angle = ((Integer)curelement.getValue(VectorElement.ANGLE, -1)).intValue();
				
				int ax = prevx + (int)(AuxMath.cos(angle) * rx);
				int ay = prevy - (int)(AuxMath.sin(angle) * ry);
				
				moveCursor(ax, ay);
			}
			else if(editstate == 3)
			{
				editstate = 2;
				
				info[3] = CODES[SIZE];
				
				prevx = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				prevy = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				int ax = prevx + curelement.getScaled(((Double)curelement.getValue(VectorElement.WIDTH, -1)).doubleValue(), 2) / 2;
				int ay = prevy + curelement.getScaled(((Double)curelement.getValue(VectorElement.HEIGHT, -1)).doubleValue(), 3) / 2;
				
				moveCursor(ax, ay);
			}
			else if(editstate == 2)
			{
				editstate = 1;
				
				info[3] = CODES[POSITION];
				
				int ax = curelement.getScaled(((Double)curelement.getValue(VectorElement.X, -1)).doubleValue(), 0);
				int ay = curelement.getScaled(((Double)curelement.getValue(VectorElement.Y, -1)).doubleValue(), 1);
				
				moveCursor(ax, ay);
			}
		}
	}
	
	protected void setTransformPacket()
	{
		TransformPacket packet;
		
		for(int i = 0; i < transpackets.size(); i++)
		{
			packet = (TransformPacket)transpackets.elementAt(i);
			
			if(packet.getElement() == curelement)
			{
				return;
			}
		}
		
		packet = new TransformPacket(curelement);
		
		if(elemtype == VectorElement.LINE)
		{
			packet.addTransform(VectorElement.X, 1);
			packet.addTransform(VectorElement.Y, 1);
			packet.addTransform(VectorElement.X, 2);
			packet.addTransform(VectorElement.Y, 2);
		}
		else if(elemtype == VectorElement.ARC)
		{
			packet.addTransform(VectorElement.X, -1);
			packet.addTransform(VectorElement.Y, -1);
			packet.addTransform(VectorElement.WIDTH, -1);
			packet.addTransform(VectorElement.HEIGHT, -1);
			packet.addTransform(VectorElement.START, -1);
			packet.addTransform(VectorElement.LENGTH, -1);
		}
		else if(elemtype == VectorElement.RECT)
		{
			packet.addTransform(VectorElement.X, -1);
			packet.addTransform(VectorElement.Y, -1);
			packet.addTransform(VectorElement.WIDTH, -1);
			packet.addTransform(VectorElement.HEIGHT, -1);
		}
		else if(elemtype == VectorElement.ROUND_RECT)
		{
			packet.addTransform(VectorElement.X, -1);
			packet.addTransform(VectorElement.Y, -1);
			packet.addTransform(VectorElement.WIDTH, -1);
			packet.addTransform(VectorElement.HEIGHT, -1);
			packet.addTransform(VectorElement.ARC_WIDTH, -1);
			packet.addTransform(VectorElement.ARC_HEIGHT, -1);
		}
		else if(elemtype == VectorElement.POINT)
		{
			packet.addTransform(VectorElement.X, 1);
			packet.addTransform(VectorElement.Y, 1);
		}
		else if(elemtype == VectorElement.TRIANGLE)
		{
			packet.addTransform(VectorElement.X, 1);
			packet.addTransform(VectorElement.Y, 1);
			packet.addTransform(VectorElement.X, 2);
			packet.addTransform(VectorElement.Y, 2);
			packet.addTransform(VectorElement.X, 3);
			packet.addTransform(VectorElement.Y, 3);
		}
		else if(elemtype == VectorElement.POLYLINE)
		{
			for(int i = 1; i <= pointcount; i++)
			{
				packet.addTransform(VectorElement.X, i);
				packet.addTransform(VectorElement.Y, i);
			}
		}
		else if(elemtype == VectorElement.POLYGON)
		{
			packet.addTransform(VectorElement.X, -1);
			packet.addTransform(VectorElement.Y, -1);
			packet.addTransform(VectorElement.WIDTH, -1);
			packet.addTransform(VectorElement.HEIGHT, -1);
			packet.addTransform(VectorElement.ROTATION, -1);
			packet.addTransform(VectorElement.ANGLE, -1);
		}
		else if(elemtype == VectorElement.BEZIER_CURVE)
		{
			for(int i = 1; i <= pointcount; i++)
			{
				packet.addTransform(VectorElement.X, i);
				packet.addTransform(VectorElement.Y, i);
			}
		}
		else if(elemtype == VectorElement.THICK_LINE)
		{
			packet.addTransform(VectorElement.X, 1);
			packet.addTransform(VectorElement.Y, 1);
			packet.addTransform(VectorElement.X, 2);
			packet.addTransform(VectorElement.Y, 2);
			packet.addTransform(VectorElement.THICKNESS, -1);
		}
		else if(elemtype == VectorElement.THICK_RECT)
		{
			packet.addTransform(VectorElement.X, -1);
			packet.addTransform(VectorElement.Y, -1);
			packet.addTransform(VectorElement.WIDTH, -1);
			packet.addTransform(VectorElement.HEIGHT, -1);
			packet.addTransform(VectorElement.THICKNESS, -1);
		}
		else if(elemtype == VectorElement.THICK_TRIANGLE)
		{
			packet.addTransform(VectorElement.X, 1);
			packet.addTransform(VectorElement.Y, 1);
			packet.addTransform(VectorElement.X, 2);
			packet.addTransform(VectorElement.Y, 2);
			packet.addTransform(VectorElement.X, 3);
			packet.addTransform(VectorElement.Y, 3);
			packet.addTransform(VectorElement.THICKNESS, -1);
		}
		else if(elemtype == VectorElement.THICK_POLYLINE)
		{
			for(int i = 1; i <= pointcount; i++)
			{
				packet.addTransform(VectorElement.X, i);
				packet.addTransform(VectorElement.Y, i);
			}
			
			packet.addTransform(VectorElement.THICKNESS, -1);
		}
		else if(elemtype == VectorElement.THICK_POLYGON)
		{
			packet.addTransform(VectorElement.X, -1);
			packet.addTransform(VectorElement.Y, -1);
			packet.addTransform(VectorElement.WIDTH, -1);
			packet.addTransform(VectorElement.HEIGHT, -1);
			packet.addTransform(VectorElement.ROTATION, -1);
			packet.addTransform(VectorElement.ANGLE, -1);
			packet.addTransform(VectorElement.THICKNESS, -1);
		}
		else if(elemtype == VectorElement.THICK_BEZIER_CURVE)
		{
			for(int i = 1; i <= pointcount; i++)
			{
				packet.addTransform(VectorElement.X, i);
				packet.addTransform(VectorElement.Y, i);
			}
			
			packet.addTransform(VectorElement.THICKNESS, -1);
		}
		else if(elemtype == VectorElement.GRADIENT_RECT)
		{
			packet.addTransform(VectorElement.X, -1);
			packet.addTransform(VectorElement.Y, -1);
			packet.addTransform(VectorElement.WIDTH, -1);
			packet.addTransform(VectorElement.HEIGHT, -1);
			packet.addTransform(VectorElement.ANGLE, -1);
		}
		else if(elemtype == VectorElement.GRADIENT_CIRCLE)
		{
			packet.addTransform(VectorElement.X, -1);
			packet.addTransform(VectorElement.Y, -1);
			packet.addTransform(VectorElement.WIDTH, -1);
			packet.addTransform(VectorElement.HEIGHT, -1);
			packet.addTransform(VectorElement.ANGLE, -1);
		}
		
		transpackets.addElement(packet);
	}
}