package filemanager;

import com.one.AbstractFont;
import com.one.ExtGraphics;
import javax.microedition.lcdui.*;
import java.util.Vector;
import com.vmx.*;

public class CommandMenu
{
	protected Displayable caller;
	
	protected AbstractFont font;
	protected boolean lskp, rskp;
	protected String lsktext, rsktext;
	protected int lskx, rskx, sky, skh;
	protected int w2, h2;
	protected int width, height;
	
	protected Vector commands;
	protected boolean inmenu;
	protected int mx, my, mw, mh, mlh;
	protected CommandListener listener;
	protected int msel;
	protected int iok, icancel;
	protected boolean okp, cancelp;
	protected HotKeyListener hklistener;
	protected boolean hkmode;
	protected boolean skvisible;
	protected Image drap;
	
	protected boolean center;
	protected boolean extkey;
	protected boolean hotkey;
	protected boolean hidesoft;
	protected boolean showdrap;

	/**
	 * Создать командное меню.
	 *
	 * @param caller Displayable, который будет передаваться вторым параметром в commandAction()
	 * @param hklistener обработчик "горячих клавиш", или null
	 * @param width ширина экрана
	 * @param height высота экрана
	 * @param fntsize размер шрифта (константа из AbstractFont)
	 * @param center центрировать меню на экране, или прилепить к правому софту
	 * @param extkey использовать ли цифровые клавиши для управления меню
	 * @param hotkey разрешить ли режим "горячих клавиш"
	 * @param hidesoft скрывать ли софт-строку, когда мы не в меню
	 * @param showdrap драпировать ли фон, когда мы в меню
	 */
	public CommandMenu(Displayable caller, HotKeyListener hklistener, int width, int height, int fntsize, boolean center, boolean extkey, boolean hotkey, boolean hidesoft, boolean showdrap)
	{
		this.caller = caller;
		this.hklistener = hklistener;
		
		this.width = width;
		this.height = height;
		
		this.center = center;
		this.extkey = extkey;
		this.hotkey = hotkey;
		this.hidesoft = hidesoft;
		this.showdrap = showdrap;
		
		if(showdrap)
		{
			int[] rgb = new int[width * height];
			
			for(int i = 0; i < rgb.length; i++)
			{
				rgb[i] = ColorScheme.colors[ColorScheme.drap];
			}
			
			drap = Image.createRGBImage(rgb, width, height, true);
		}
		
		font = AbstractFont.getFont(AbstractFont.FACE_SYSTEM, AbstractFont.STYLE_PLAIN, fntsize);
		
		skh = font.getHeight() + font.getHeight() / 3;
		w2 = width / 2;
		h2 = height - skh;
		
		lsktext = "";
		rsktext = "";
		
		lskp = false;
		rskp = false;
		
		sky = h2 + (skh - font.getHeight()) / 2;
		lskx = (w2 - font.stringWidth(lsktext)) / 2;
		rskx = w2 + (w2 - font.stringWidth(rsktext)) / 2;
		
		skvisible = false;
		
		commands = new Vector();
		
		iok = -1;
		icancel = -1;
		
		okp = false;
		cancelp = false;
		
		inmenu = false;
		mw = w2;
		mh = 0;
		mx = w2;
		my = height - skh - mh;
		mlh = skh;
	}
	
	public int getSoftHeight()
	{
		return skh;
	}
	
	public boolean isInMenu()
	{
		return inmenu;
	}
	
	public void addCommand(Command c)
	{
		if(commands.contains(c))
		{
			return;
		}
		
		boolean added = false;
		int i;
		
		for(i = 0; i < commands.size(); i++)
		{
			if(((Command)commands.elementAt(i)).getPriority() > c.getPriority())
			{
				commands.insertElementAt(c, i);
				added = true;
				break;
			}
		}
		
		if(!added)
		{
			commands.addElement(c);
		}
		
		iok = -1;
		icancel = -1;
		
		if(extkey)
		{
			for(i = 0; i < commands.size(); i++)
			{
				c = (Command)commands.elementAt(i);
				
				if(iok < 0 && (c.getCommandType() == Command.OK ||
				               c.getCommandType() == Command.ITEM))
				{
					iok = i;
				}
				else if(icancel < 0 && (c.getCommandType() == Command.CANCEL ||
				                        c.getCommandType() == Command.BACK ||
				                        c.getCommandType() == Command.EXIT))
				{
					icancel = i;
				}
			}
		}
		
		lsktext = ((Command)commands.elementAt(0)).getLabel();
		
		if(commands.size() == 2)
		{
			rsktext = ((Command)commands.elementAt(1)).getLabel();
		}
		else if(commands.size() > 2)
		{
			rsktext = Locale.getString(this, Locale.OPTIONS_CMD);
			
			if(center)
			{
				mw = 0;
				int sw;
				
				for(i = 1; i < commands.size(); i++)
				{
					sw = font.stringWidth(((Command)commands.elementAt(i)).getLabel()) + font.getHeight() / 3 * 2;
					
					if(sw > mw)
					{
						mw = sw;
					}
				}
				
				mx = (width - mw) / 2;
				
				mh = (commands.size() - 1) * mlh;
				my = (height - mh) / 2;
			}
			else
			{
				mh = (commands.size() - 1) * mlh;
				my = height - skh - mh + 1;
			}
		}
		else
		{
			rsktext = "";
		}
		
		lskx = (w2 - font.stringWidth(lsktext)) / 2;
		rskx = w2 + (w2 - font.stringWidth(rsktext)) / 2;
	}
	
	public void removeCommand(Command c)
	{
		if(!commands.contains(c))
		{
			return;
		}
		
		commands.removeElement(c);
		
		iok = -1;
		icancel = -1;
		
		if(extkey)
		{
			for(int i = 0; i < commands.size(); i++)
			{
				c = (Command)commands.elementAt(i);
				
				if(iok < 0 && (c.getCommandType() == Command.OK ||
				               c.getCommandType() == Command.ITEM))
				{
					iok = i;
				}
				else if(icancel < 0 && (c.getCommandType() == Command.CANCEL ||
				                        c.getCommandType() == Command.BACK ||
				                        c.getCommandType() == Command.EXIT))
				{
					icancel = i;
				}
			}
		}
		
		if(commands.size() > 0)
		{
			lsktext = ((Command)commands.elementAt(0)).getLabel();
			
			if(commands.size() == 2)
			{
				rsktext = ((Command)commands.elementAt(1)).getLabel();
			}
			else if(commands.size() > 2)
			{
				rsktext = Locale.getString(this, Locale.OPTIONS_CMD);
				
				if(center)
				{
					mw = 0;
					int i, sw;
					
					for(i = 1; i < commands.size(); i++)
					{
						sw = font.stringWidth(((Command)commands.elementAt(i)).getLabel()) + font.getHeight() / 3 * 2;
						
						if(sw > mw)
						{
							mw = sw;
						}
					}
					
					mx = (width - mw) / 2;
					
					mh = (commands.size() - 1) * mlh;
					my = (height - mh) / 2;
				}
				else
				{
					mh = (commands.size() - 1) * mlh;
					my = height - skh - mh + 1;
				}
			}
			else
			{
				rsktext = "";
			}
		}
		else
		{
			lsktext = "";
			rsktext = "";
		}
		
		lskx = (w2 - font.stringWidth(lsktext)) / 2;
		rskx = w2 + (w2 - font.stringWidth(rsktext)) / 2;
	}
	
	public void removeAllCommands()
	{
		commands.removeAllElements();
		
		iok = -1;
		icancel = -1;
		
		lsktext = "";
		rsktext = "";
		
		lskx = (w2 - font.stringWidth(lsktext)) / 2;
		rskx = w2 + (w2 - font.stringWidth(rsktext)) / 2;
	}
	
	public int commandCount()
	{
		return commands.size();
	}
	
	public void setCommandListener(CommandListener cl)
	{
		listener = cl;
	}
	
	public CommandListener getCommandListener()
	{
		return listener;
	}
	
	public void commandAction(Command c, Displayable dp)
	{
		if(listener != null)
		{
			listener.commandAction(c, dp);
		}
	}
	
	public boolean keyPressed(int keyCode)
	{
		if(hotkey && hkmode)
		{
			hkmode = false;
			
			int index = keyCode - gkcCanvas.KEY_NUM0;
			
			if(index >= 0 && index < commands.size() && listener != null)
			{
				listener.commandAction((Command)commands.elementAt(index), caller);
			}
			else if(hklistener != null)
			{
				hklistener.hotKeyAction(keyCode);
			}
			
			return true;
		}
		
		if(extkey)
		{
			keyCode = gkcCanvas.translateKey(keyCode);
			
			if(keyCode == gkcCanvas.KEY_NUM1)
			{
				keyCode = gkcCanvas.KEY_LSK;
			}
			else if(keyCode == gkcCanvas.KEY_NUM3)
			{
				keyCode = gkcCanvas.KEY_RSK;
			}
		}
		
		if(inmenu)
		{
			if(keyCode == gkcCanvas.KEY_LSK ||
			   keyCode == gkcCanvas.KEY_LEFT ||
			   keyCode == gkcCanvas.KEY_CANCEL)
			{
				inmenu = false;
				skvisible = false;
			}
			else if(keyCode == gkcCanvas.KEY_RSK ||
			        keyCode == gkcCanvas.KEY_FIRE ||
			        keyCode == gkcCanvas.KEY_RIGHT ||
			        keyCode == gkcCanvas.KEY_DIAL)
			{
				inmenu = false;
				skvisible = false;
				
				if(listener != null)
				{
					listener.commandAction((Command)commands.elementAt(msel + 1), caller);
				}
			}
			else if(keyCode == gkcCanvas.KEY_UP)
			{
				if(--msel < 0)
				{
					msel = commands.size() - 2;
				}
			}
			else if(keyCode == gkcCanvas.KEY_DOWN)
			{
				if(++msel > commands.size() - 2)
				{
					msel = 0;
				}
			}
			else
			{
				return false;
			}
			
			return true;
		}
		else
		{
			if(hotkey && keyCode == gkcCanvas.KEY_POUND)
			{
				hkmode = true;
				return true;
			}
			
			if(extkey)
			{
				if(keyCode == gkcCanvas.KEY_FIRE)
				{
					if(options.noEffects)
					{
						skvisible = false;

						if(iok >= 0 && listener != null)
						{
							listener.commandAction((Command)commands.elementAt(iok), caller);
						}

						return hidesoft;
					}
					else
					{
						okp = true;

						if(iok == 0)
						{
							lskp = true;
							skvisible = hidesoft;
						}
						else if(iok == 1 && commands.size() == 2)
						{
							rskp = true;
							skvisible = hidesoft;
						}

						return true;
					}
				}
				else if(keyCode == gkcCanvas.KEY_CANCEL)
				{
					if(options.noEffects)
					{
						skvisible = false;

						if(icancel >= 0 && listener != null)
						{
							listener.commandAction((Command)commands.elementAt(icancel), caller);
						}

						return hidesoft;
					}
					else
					{
						cancelp = true;

						if(icancel == 0)
						{
							lskp = true;
							skvisible = hidesoft;
						}
						else if(icancel == 1 && commands.size() == 2)
						{
							rskp = true;
							skvisible = hidesoft;
						}

						return true;
					}
				}
			}
			
			if(skvisible || !hidesoft)
			{
				if(keyCode == gkcCanvas.KEY_LSK)
				{
					if(options.noEffects)
					{
						skvisible = false;

						if(commands.size() > 0 && listener != null)
						{
							listener.commandAction((Command)commands.elementAt(0), caller);
						}

						return hidesoft;
					}
					else
					{
						lskp = true;
					}
				}
				else if(keyCode == gkcCanvas.KEY_RSK)
				{
					if(options.noEffects)
					{
						if(commands.size() > 2)
						{
							inmenu = true;

							if(msel < 0)
							{
								msel = 0;
							}
							else if(msel > commands.size() - 2)
							{
								msel = commands.size() - 2;
							}

							return true;
						}
						else
						{
							skvisible = false;

							if(commands.size() == 2 && listener != null)
							{
								listener.commandAction((Command)commands.elementAt(1), caller);
							}

							return hidesoft;
						}
					}
					else
					{
						rskp = true;
					}
				}
				else if(hidesoft)
				{
					skvisible = false;
				}
				else
				{
					return false;
				}
				
				return true;
			}
			else
			{
				if(keyCode == gkcCanvas.KEY_LSK ||
				   keyCode == gkcCanvas.KEY_RSK)
				{
					skvisible = true;
				}
				else
				{
					return false;
				}
				
				return true;
			}
		}
	}
	
	public boolean keyReleased(int keyCode)
	{
		if(inmenu)
		{
			return true;
		}
		
		if(extkey)
		{
			keyCode = gkcCanvas.translateKey(keyCode);
			
			if(keyCode == gkcCanvas.KEY_NUM1)
			{
				keyCode = gkcCanvas.KEY_LSK;
			}
			else if(keyCode == gkcCanvas.KEY_NUM3)
			{
				keyCode = gkcCanvas.KEY_RSK;
			}
			
			if(keyCode == gkcCanvas.KEY_FIRE)
			{
				if(okp)
				{
					okp = false;
					
					if(iok == 0)
					{
						lskp = false;
						skvisible = false;
					}
					else if(iok == 1 && commands.size() == 2)
					{
						rskp = false;
						skvisible = false;
					}
					
					if(iok >= 0 && listener != null)
					{
						listener.commandAction((Command)commands.elementAt(iok), caller);
					}
					
					return true;
				}
			}
			else if(keyCode == gkcCanvas.KEY_CANCEL)
			{
				if(cancelp)
				{
					cancelp = false;
					
					if(icancel == 0)
					{
						lskp = false;
						skvisible = false;
					}
					else if(icancel == 1 && commands.size() == 2)
					{
						rskp = false;
						skvisible = false;
					}
					
					if(icancel >= 0 && listener != null)
					{
						listener.commandAction((Command)commands.elementAt(icancel), caller);
					}
					
					return true;
				}
			}
		}
		
		if(skvisible || !hidesoft)
		{
			if(keyCode == gkcCanvas.KEY_LSK)
			{
				if(lskp)
				{
					lskp = false;
					skvisible = false;
					
					if(commands.size() > 0 && listener != null)
					{
						listener.commandAction((Command)commands.elementAt(0), caller);
					}
					
					return true;
				}
			}
			else if(keyCode == gkcCanvas.KEY_RSK)
			{
				if(rskp)
				{
					rskp = false;
					
					if(commands.size() > 2)
					{
						inmenu = true;
						
						if(msel < 0)
						{
							msel = 0;
						}
						else if(msel > commands.size() - 2)
						{
							msel = commands.size() - 2;
						}
					}
					else
					{
						skvisible = false;
						
						if(commands.size() == 2 && listener != null)
						{
							listener.commandAction((Command)commands.elementAt(1), caller);
						}
					}
					
					return true;
				}
			}
		}
		
		return false;
	}
	
	public void paint(ExtGraphics g)
	{
		g.setFont(font);
		
		if(showdrap && (inmenu || skvisible))
		{
			g.drawImage(drap, 0, 0, Graphics.LEFT | Graphics.TOP);
		}
		
		if(skvisible || !hidesoft)
		{
			if(lskp)
			{
				//g.setColor(ColorScheme.colors[ColorScheme.selback1]);
				//g.fillRect(0, h2, w2, skh);
				images.drawHGradient(g, ColorScheme.colors[ColorScheme.skselback1], ColorScheme.colors[ColorScheme.skselback2], 0, h2, w2, skh, options.ditherGradients);
				g.setColor(ColorScheme.colors[ColorScheme.skselfore]);
			}
			else
			{
				//g.setColor(ColorScheme.colors[ColorScheme.back1]);
				//g.fillRect(0, h2, w2, skh);
				g.setColor(ColorScheme.colors[ColorScheme.skfore]);
			}
			
			g.drawString(lsktext, lskx, sky, Graphics.LEFT | Graphics.TOP);
			
			if(rskp)
			{
				//g.setColor(ColorScheme.colors[ColorScheme.selback1]);
				//g.fillRect(w2, h2, w2, skh);
				images.drawHGradient(g, ColorScheme.colors[ColorScheme.skselback2], ColorScheme.colors[ColorScheme.skselback1], w2, h2, w2, skh, options.ditherGradients);
				g.setColor(ColorScheme.colors[ColorScheme.skselfore]);
			}
			else
			{
				//g.setColor(ColorScheme.colors[ColorScheme.back1]);
				//g.fillRect(w2, h2, w2, skh);
				g.setColor(ColorScheme.colors[ColorScheme.skfore]);
			}
			
			g.drawString(rsktext, rskx, sky, Graphics.LEFT | Graphics.TOP);
			
			g.setColor(ColorScheme.colors[ColorScheme.ltborder]);
			g.drawRect(0, h2, w2, skh - 1);
			g.drawRect(w2, h2, w2 - 1, skh - 1);
		}
		
		if(inmenu)
		{
			//g.setColor(ColorScheme.colors[ColorScheme.back1]);
			//g.fillRect(mx, my, mw, mh);

			images.drawVGradient(g, ColorScheme.colors[ColorScheme.mnback1], ColorScheme.colors[ColorScheme.mnback2], mx, my, mw, mh, options.ditherGradients);
			
			g.setColor(ColorScheme.colors[ColorScheme.ltborder]);
			g.drawRect(mx, my, mw - 1, mh - 1);
			
			String s;
			int x, y;
			
			for(int i = 0; i < commands.size() - 1; i++)
			{
				s = ((Command)commands.elementAt(i + 1)).getLabel();
				x = mx + (mw - font.stringWidth(s)) / 2;
				y = my + i * mlh + (mlh - font.getHeight()) / 2;
				
				if(i == msel)
				{
					//g.setColor(ColorScheme.colors[ColorScheme.selback1]);
					//g.fillRect(mx, my + i * mlh, mw, mlh);

					images.drawHGradient(g, ColorScheme.colors[ColorScheme.mnselback1], ColorScheme.colors[ColorScheme.mnselback2], mx, my + i * mlh, mw, mlh, options.ditherGradients);
					
					g.setColor(ColorScheme.colors[ColorScheme.mnselfore]);
					g.drawString(s, x, y, Graphics.LEFT | Graphics.TOP);
					
					g.setColor(ColorScheme.colors[ColorScheme.ltborder]);
					g.drawRect(mx, my + i * mlh, mw - 1, mlh - 1);
				}
				else
				{
					g.setColor(ColorScheme.colors[ColorScheme.mnfore]);
					g.drawString(s, x, y, Graphics.LEFT | Graphics.TOP);
				}
			}
		}
	}
}
