/*
 * Copyright © 2000-2005 Canoo Engineering AG, Switzerland.
 */
package com.canoo.ulc.playground.developerlist;

import com.ulcjava.base.application.AbstractApplication;
import com.ulcjava.base.application.ULCBoxPane;
import com.ulcjava.base.application.ULCButton;
import com.ulcjava.base.application.ULCFrame;
import com.ulcjava.base.application.ULCProxy;
import com.ulcjava.base.application.ULCTextField;
import com.ulcjava.base.application.event.IActionListener;
import com.ulcjava.base.application.event.ActionEvent;
import com.ulcjava.base.client.datatype.DataTypeConversionException;
import com.ulcjava.base.client.datatype.UIDataType;
import com.ulcjava.base.development.DevelopmentRunner;
import com.ulcjava.base.shared.internal.Anything;

public class MyRegexpDatatypeSnippet extends AbstractApplication {
    public void start() {
        ULCBoxPane content = new ULCBoxPane(true);

        final ULCMyRegexpDataType dataType = new ULCMyRegexpDataType();
        ULCTextField textField = new ULCTextField();
        textField.setDataType(dataType);
        content.add(ULCBoxPane.BOX_EXPAND_EXPAND, textField);

        ULCButton button = new ULCButton("Configure datatype");
        button.addActionListener(new IActionListener() {
            public void actionPerformed(ActionEvent event) {
                dataType.setInputFilterExpression("[0-9]*");
                dataType.setValidateExpression("[0-9]{5,10}");
            }
        });
        content.add(ULCBoxPane.BOX_EXPAND_EXPAND, button);

        ULCFrame frame = new ULCFrame("MyRegexpDatatypeSnippet");
        frame.setDefaultCloseOperation(ULCFrame.TERMINATE_ON_CLOSE);
        frame.add(content);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        DevelopmentRunner.setApplicationClass(MyRegexpDatatypeSnippet.class);
        DevelopmentRunner.main(args);
    }

    public static class ULCMyRegexpDataType extends ULCProxy implements com.ulcjava.base.application.datatype.IDataType {
        private static final String DEFAULT_REGEXP = ".*";
        private String fInputFilterExpression;
        private String fValidateExpression;

        public void setInputFilterExpression(String inputFilterExpression) {
            fInputFilterExpression = update("setInputFilterExpression", fInputFilterExpression, inputFilterExpression);
        }

        public void setValidateExpression(String validateExpression) {
            fValidateExpression = update("setValidateExpression", fValidateExpression, validateExpression);
        }

        protected void saveState(Anything a) {
            super.saveState(a);
            saveState(a, "inputFilterExpression", fInputFilterExpression, DEFAULT_REGEXP);
            saveState(a, "validateExpression", fValidateExpression, DEFAULT_REGEXP);
        }

        protected String typeString() {
            return UIMyRegexpDataType.class.getName();
        }
    }

    public static class UIMyRegexpDataType extends UIDataType {
        private static final String DEFAULT_REGEXP = ".*";
        private String fInputFilterExpression;
        private String fValidateExpression;

        public UIMyRegexpDataType() {
            fInputFilterExpression = DEFAULT_REGEXP;
            fValidateExpression = DEFAULT_REGEXP;
        }

        public void handleRequest(String request, Anything args) {
            if ("setInputFilterExpression".equals(request)) {
                setInputFilterExpression(args.asString(DEFAULT_REGEXP));
            } else if ("setValidateExpression".equals(request)) {
                setValidateExpression(args.asString(DEFAULT_REGEXP));
            } else {
                super.handleRequest(request, args);
            }
        }

        public void restoreState(Anything args) {
            super.restoreState(args);

            if (args.isDefined("inputFilterExpression")) {
                setInputFilterExpression(args.get("inputFilterExpression").asString(DEFAULT_REGEXP));
            }
            if (args.isDefined("validateExpression")) {
                setValidateExpression(args.get("validateExpression").asString(DEFAULT_REGEXP));
            }
        }

        private void setInputFilterExpression(String inputFilterExpression) {
            fInputFilterExpression = inputFilterExpression;
        }

        private void setValidateExpression(String validateExpression) {
            fValidateExpression = validateExpression;
        }

        /**
         * This method is called on focus lost. This method returns the value of the String as defined by the
         * datatype. For our case, it is again a String object. In case of a NumberDataType, it would parse the String
         * and return a Number object.
         *
         * @param newString the new text string
         * @param previousValue the last consistent value
         * @return returns the value of the String as defined by the datatypefor our case, it is again
         *         a String object)
         */
        public Object convertToObject(String newString, Object previousValue) throws DataTypeConversionException {
            if (newString.matches(fValidateExpression)) {
                return newString;
            } else {
                throw new DataTypeConversionException("illegal input", previousValue);
            }
        }

        /**
         * This method is called on every keystroke. It returns the String that is accepted by the datatype,
         * i.e., the string that really should be inserted.
         *
         * @param newString the newly inserted text string (maybe multiple chars, e.g.,  in case of copy & paste)
         * @return returns the String that is accepted by the datatype
         */
        public String filterInput(String newString) {
            if (newString.matches(fInputFilterExpression)) {
                return newString;
            } else {
                return null;
            }
        }
    }
}