/*******************************************************************************
 * Copyright (c) 2004, 2015 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.ui.actions;

import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.debug.ui.actions.IVariableValueEditor;
import org.eclipse.jdt.internal.debug.eval.ast.engine.ASTInstructionCompiler;
import org.eclipse.jdt.internal.debug.ui.IJavaDebugHelpContextIds;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;

/**
 * A variable value editor that prompts the user to set a primitive's value.
 */
public class JavaPrimitiveValueEditor implements IVariableValueEditor {

    /**
     * The signature of the edited variable.
     */
    private String fSignature= null;

    /**
     * Creates a new editor for a variable with the given signature
     * @param signature the signature of the primitive to be edited
     */
    public JavaPrimitiveValueEditor(String signature) {
        fSignature= signature;
    }

    /* (non-Javadoc)
     * @see org.eclipse.debug.ui.actions.IVariableValueEditor#editVariable(org.eclipse.debug.core.model.IVariable, org.eclipse.swt.widgets.Shell)
     */
    @Override
	public boolean editVariable(IVariable variable, Shell shell) {
        try {
            String name= variable.getName();
            String title= ActionMessages.JavaPrimitiveValueEditor_0;
            String message= NLS.bind(ActionMessages.JavaPrimitiveValueEditor_1, new String[] {name});
            String initialValue= variable.getValue().getValueString();
            PrimitiveValidator validator= new PrimitiveValidator();
            InputDialog dialog= new InputDialog(shell, title, message, initialValue, validator){
            	@Override
				protected Control createDialogArea(Composite parent) {
            		IWorkbench workbench = PlatformUI.getWorkbench();
            		workbench.getHelpSystem().setHelp(parent, IJavaDebugHelpContextIds.DEFAULT_INPUT_DIALOG);
            		return super.createDialogArea(parent);
            	}
            };
            if (dialog.open() == Window.OK) {
                String stringValue = dialog.getValue();
                stringValue = formatValue(stringValue);
                if (stringValue.length() > 1 && stringValue.charAt(0) == '\\') {
                	// Compute value of octal of hexadecimal escape sequence
                	int i= validator.getEscapeValue(stringValue);
                	if (i != Integer.MAX_VALUE) {
                		stringValue= new String(new char[] { (char) i });
                	}
                }
                variable.setValue(stringValue);
            }
        } catch (DebugException e) {
            JDIDebugUIPlugin.errorDialog(shell, ActionMessages.JavaPrimitiveValueEditor_2, ActionMessages.JavaPrimitiveValueEditor_3, e); //
        }
        return true;
    }

    /* (non-Javadoc)
     * @see org.eclipse.debug.ui.actions.IVariableValueEditor#saveVariable(org.eclipse.debug.core.model.IVariable, java.lang.String, org.eclipse.swt.widgets.Shell)
     */
    @Override
	public boolean saveVariable(IVariable variable, String expression, Shell shell) {
        return false;
    }

    String formatValue(String value) {
    	try {
	    	switch (fSignature.charAt(0)) {
		    	case 'I':
	    	    	return Integer.toString(ASTInstructionCompiler.parseIntValue(value));
		    	case 'J':
	    	    	return Long.toString(ASTInstructionCompiler.parseLongValue(value));
		    	case 'S':
	                return Short.toString(ASTInstructionCompiler.parseShortValue(value));
		    	case 'F':
		    	case 'D':
		    		return ASTInstructionCompiler.removePrefixZerosAndUnderscores(value, false);
		    	case 'B':
		    		return Byte.toString(ASTInstructionCompiler.parseByteValue(value));
		    }
    	}
    	catch(NumberFormatException nfe) {}
    	return value;
    }

    /**
     * Input validator for primitive types
     */
    protected class PrimitiveValidator implements IInputValidator {
        /* (non-Javadoc)
         * @see org.eclipse.jface.dialogs.IInputValidator#isValid(java.lang.String)
         */
        @Override
		public String isValid(String newText) {
            String type= null;
            switch (fSignature.charAt(0)) {
	        	case 'B':
	        	    try {
		        	    Byte.parseByte(newText);
	                } catch (NumberFormatException e) {
	                    type= "byte"; //$NON-NLS-1$
	                }
	                break;
	        	case 'C':
	        		if (newText.length() > 1 && newText.charAt(0) == '\\') {
	        			// Possibly an escaped character
	        			if (isSpecialCharacter(newText) ||
	        					isOctalEscape(newText) ||
	        					isUnicode(newText)) {
	        				break;
	        			}
	        		}
	        		if (newText.length() != 1) {
	        	        type="char"; //$NON-NLS-1$
	        	    }
	                break;
	        	case 'D':
	        	    try {
	                    Double.parseDouble(ASTInstructionCompiler.removePrefixZerosAndUnderscores(newText, false));
	                } catch (NumberFormatException e) {
	        	        type="double"; //$NON-NLS-1$
	                }
	                break;
	        	case 'F':
	        	    try {
	                    Float.parseFloat(ASTInstructionCompiler.removePrefixZerosAndUnderscores(newText, false));
	                } catch (NumberFormatException e) {
	        	        type="float"; //$NON-NLS-1$
	                }
	                break;
            	case 'I':
            	    try {
            	    	ASTInstructionCompiler.parseIntValue(newText);
                    } catch (NumberFormatException e) {
	        	        type="int"; //$NON-NLS-1$
                    }
                    break;
	        	case 'J':
	        	    try {
	        	    	ASTInstructionCompiler.parseLongValue(newText);
	                } catch (NumberFormatException e) {
	        	        type="long"; //$NON-NLS-1$
	                }
	                break;
	        	case 'S':
	        	    try {
	                    ASTInstructionCompiler.parseShortValue(newText);
	                } catch (NumberFormatException e) {
	        	        type="short"; //$NON-NLS-1$
	                }
	                break;
	        	case 'Z':
                    if (!("true".equals(newText) || "false".equals(newText))) { //$NON-NLS-1$ //$NON-NLS-2$
						type="boolean"; //$NON-NLS-1$
                    }
	                break;
            }
            if (type != null) {
                return NLS.bind(ActionMessages.JavaPrimitiveValueEditor_4, new String[] { type });
            }
            return null;
        }

		private boolean isUnicode(String newText) {
			if (newText.length() == 6) {
				if (newText.charAt(1) == 'u') {
					char[] chars = newText.toCharArray();
					for (int i = 2; i < chars.length; i++) {
						if (!isHexDigit(chars[i])) {
							return false;
						}
					}
					return true;
				}
			}
			return false;
		}

		private boolean isOctalEscape(String newText) {
			char[] chars= newText.toCharArray();
			if (chars.length < 4) {
				for (int i = 1; i < chars.length; i++) {
					if (!isOctalDigit(chars[i])) {
						return false;
					}
				}
				return true;
			} else if (chars.length == 4) {
				char ch= chars[1];
				if (ch < '0' || ch > '3') {
					return false;
				}
				for (int i = 2; i < chars.length; i++) {
					if (!isOctalDigit(chars[i])) {
						return false;
					}
				}
                return true;
			}
			return false;
		}

		private boolean isSpecialCharacter(String newText) {
			char ch= newText.charAt(1);
			return newText.length() == 2 &&
				(ch == 'b'  ||
				ch == 't'  ||
				ch == 'n'  ||
				ch == 'f'  ||
				ch == 'r'  ||
				ch == '"'  ||
				ch == '\'' ||
				ch == '\\');
		}


		private boolean isOctalDigit(char ch) {
            return Character.digit(ch, 8) != -1;
		}

		private boolean isHexDigit(char ch) {
            return Character.digit(ch, 16) != -1;
		}

		/**
		 * Returns the integer value specified by the given string, which
		 * represents an octal or hexadecimal escape sequence. Returns
		 * Integer.MAX_VALUE if the given string is not a valid octal or
		 * hexadecimal escape sequence.
		 *
		 * @param string
		 * @return
		 */
		protected int getEscapeValue(String string) {
			return ASTInstructionCompiler.parseIntValue(string);
		}
    }

}
