package filemanager;

import javax.microedition.lcdui.*;
import java.io.IOException;
import com.one.*;
import com.vmx.*;

public class Palette extends gkcCanvas
{
	public static int[] UNIFIED_PALETTE = new int[256];
	
	public static int PALETTE_COLUMNS = 8;
	public static int PALETTE_ROWS = 6;
	
	protected static int[] colors;
	protected int colorindex;
	
	protected AbstractFont ttlfont, font;
	protected int ttlfnth, fnth;
	
	protected int width, height;
	
	protected int ttlx, ttly, ttlw, ttlh;
	
	protected int cellw, cellh;
	protected int[] cellx;
	protected int[] celly;
	
	protected String clr;
	protected int clrx, clry, clrh;
	
	protected CommandMenu cmenu;
	
	public Palette()
	{
		if(colors == null)
		{
			try
			{
				loadPalette();
				loadUnifiedPalette();
			}
			catch(IOException e)
			{
				throw new IllegalStateException("Palette not loaded: " + AuxClass.formatException(e));
			}
		}

		setFullScreenMode(true);
		
		width = getWidth();
		height = getHeight();
		
		ttlfont = AbstractFont.getFont(AbstractFont.FACE_SYSTEM, AbstractFont.STYLE_PLAIN, AbstractFont.SIZE_MEDIUM);
		font = AbstractFont.getFont(AbstractFont.FACE_SYSTEM, AbstractFont.STYLE_PLAIN, options.largeFontInMenu ? AbstractFont.SIZE_MEDIUM : AbstractFont.SIZE_SMALL);
		
		ttlfnth = ttlfont.getHeight();
		fnth = font.getHeight();
		
		ttlw = ttlfont.stringWidth(Locale.getString(this, Locale.PALETTE_CMD)) + ttlfnth;
		ttlh = ttlfnth * 3 / 2;
		ttlx = ttlfnth / 2;
		ttly = (ttlh - ttlfnth) / 2;
		
		cmenu = new CommandMenu(getRenderer(), null, width, height, options.largeFontInMenu ? AbstractFont.SIZE_MEDIUM : AbstractFont.SIZE_SMALL, true, true, false, false, false);
		
		clrh = fnth * 3 / 2;
		
		cellw = (width - fnth) / PALETTE_COLUMNS + 1;
		cellh = (height - ttlh - cmenu.getSoftHeight() - ttlfnth * 2 - clrh) / PALETTE_ROWS + 1;
		
		if(cellh > cellw)
		{
			cellh = cellw;
		}
		
		if(clrh < cellh)
		{
			clrh = cellh;
		}
		
		cellx = new int[PALETTE_COLUMNS];
		cellx[0] = (width - (cellw - 1) * PALETTE_COLUMNS) / 2;
		
		for(int i = 1; i < cellx.length; i++)
		{
			cellx[i] = cellx[i - 1] + cellw - 1;
		}
		
		celly = new int[PALETTE_ROWS + 1];
		celly[0] = ttlh + (height - ttlh - cmenu.getSoftHeight() - clrh - (cellh - 1) * PALETTE_ROWS) / 2;
		
		for(int i = 1; i < celly.length; i++)
		{
			celly[i] = celly[i - 1] + cellh - 1;
		}
		
		clr = "";
		clrx = cellx[0] + fnth / 2;
		clry = celly[PALETTE_ROWS] + (clrh - fnth) / 2;
		
		addCommand(new Command(Locale.getString(this, Locale.OK_CMD), Command.OK, 1));
		addCommand(new Command(Locale.getString(this, Locale.EDIT_CMD), Command.ITEM, 2));
		addCommand(new Command(Locale.getString(this, Locale.CANCEL_CMD), Command.CANCEL, 3));
	}
	
	public boolean setColor(int color)
	{
		colorindex = ImageProcessor.nearestColor(color, colors);
		return colors[colorindex] == color;
	}
	
	public int getColor()
	{
		return colors[colorindex];
	}
	
	public void paint(ExtGraphics g)
	{
		//g.setColor(ColorScheme.colors[ColorScheme.back1]);
		//g.fillRect(0, 0, width, height);

		images.drawVGradient(g, ColorScheme.colors[ColorScheme.back1], ColorScheme.colors[ColorScheme.back2], 0, 0, width, height, options.ditherGradients);
		
		g.setColor(ColorScheme.colors[ColorScheme.fore]);
		g.setFont(ttlfont);
		g.drawString(Locale.getString(this, Locale.PALETTE_CMD), ttlx, ttly, Graphics.LEFT | Graphics.TOP);
		
		g.setColor(ColorScheme.colors[ColorScheme.ltborder]);
		g.drawLine(0, ttlh, ttlw, ttlh);
		
		int column, row;
		int index;
		
		for(column = 0; column < PALETTE_COLUMNS; column++)
		{
			for(row = 0; row < PALETTE_ROWS; row++)
			{
				index = row + column * PALETTE_ROWS;
				
				g.setColor(colors[index]);
				g.fillRect(cellx[column], celly[row], cellw, cellh);
				
				g.setColor(ColorScheme.colors[ColorScheme.ltborder]);
				g.drawRect(cellx[column], celly[row], cellw - 1, cellh - 1);
				
				if(index == colorindex)
				{
					g.setColor(colors[index] ^ 0xC0C0C0);
					g.drawRect(cellx[column] + 2, celly[row] + 2, cellw - 5, cellh - 5);
				}
			}
		}
		
		clr = Integer.toHexString(getColor()).toUpperCase();
		
		g.setColor(colors[colorindex]);
		g.fillRect(cellx[0], celly[PALETTE_ROWS], (cellw - 1) * PALETTE_COLUMNS + 1, clrh);
		
		g.setColor(colors[colorindex] ^ 0xC0C0C0);
		g.setFont(font);
		g.drawString(clr, clrx, clry, Graphics.LEFT | Graphics.TOP);
		
		g.setColor(ColorScheme.colors[ColorScheme.ltborder]);
		g.drawRect(cellx[0], celly[PALETTE_ROWS], (cellw - 1) * PALETTE_COLUMNS, clrh - 1);
		
		cmenu.paint(g);
	}
	
	public void keyPressed(int keyCode)
	{
		keyCode = remapKey(keyCode);

		if(cmenu.keyPressed(keyCode))
		{
			repaint();
			return;
		}
		
		keyCode = translateKey(keyCode);
		
		int selcolumn = colorindex / PALETTE_ROWS;
		int selrow = colorindex % PALETTE_ROWS;
		
		if(keyCode == KEY_UP)
		{
			if(--selrow < 0)
			{
				selrow = PALETTE_ROWS - 1;
			}
		}
		else if(keyCode == KEY_DOWN)
		{
			if(++selrow >= PALETTE_ROWS)
			{
				selrow = 0;
			}
		}
		else if(keyCode == KEY_LEFT)
		{
			if(--selcolumn < 0)
			{
				selcolumn = PALETTE_COLUMNS - 1;
			}
		}
		else if(keyCode == KEY_RIGHT)
		{
			if(++selcolumn >= PALETTE_COLUMNS)
			{
				selcolumn = 0;
			}
		}
		
		colorindex = selrow + selcolumn * PALETTE_ROWS;
		
		repaint();
	}
	
	public void keyReleased(int keyCode)
	{
		keyCode = remapKey(keyCode);

		if(cmenu.keyReleased(keyCode))
		{
			repaint();
			return;
		}
	}
	
	public void addCommand(Command c)
	{
		cmenu.addCommand(c);
	}
	
	public void setCommandListener(CommandListener listener)
	{
		cmenu.setCommandListener(listener);
	}
	
	public static void loadPalette() throws IOException
	{
		InputStreamDecoder ini = InputStreamDecoder.getResourceDecoder("/config/palette.ini");
		IniRecord record = null;
		
		int state = 1;
		
		while((record = IniRecord.getNextRecord(ini)) != null)
		{
			try
			{
				if(state == 0)
				{
					colors[Integer.parseInt(record.key)] = (int)Long.parseLong(record.value, 16);
				}
				else if(state == 1)
				{
					if(record.key.equalsIgnoreCase("COLS"))
					{
						PALETTE_COLUMNS = Integer.parseInt(record.value);
						state = 2;
					}
				}
				else if(state == 2)
				{
					if(record.key.equalsIgnoreCase("ROWS"))
					{
						PALETTE_ROWS = Integer.parseInt(record.value);
						colors = new int[PALETTE_COLUMNS * PALETTE_ROWS];
						state = 0;
					}
				}
			}
			catch(Exception e)
			{
			}
		}
		
		ini.close();
	}
	
	public static void loadUnifiedPalette() throws IOException
	{
		InputStreamDecoder ini = InputStreamDecoder.getResourceDecoder("/config/unipalette.ini");
		IniRecord record = null;
		
		while((record = IniRecord.getNextRecord(ini)) != null)
		{
			try
			{
				UNIFIED_PALETTE[Integer.parseInt(record.key)] = (int)Long.parseLong(record.value, 16);
			}
			catch(Exception e)
			{
			}
		}
		
		ini.close();
	}
}