/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.examples.propertysheet;

import java.util.Vector;

import org.eclipse.jface.viewers.ICellEditorValidator;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.PropertyDescriptor;
import org.eclipse.ui.views.properties.TextPropertyDescriptor;

/**
 * Example IPropertySource who itself is NOT editable, but whose children are.
 * The values of the children determine the value of the address.
 */
public class Address implements IPropertySource {

    //properties
    private String city;

    private Integer province;

    private String postalCode;

    private StreetAddress street;

    //Property unique keys
    public static final String P_ID_STREET = "Address.Street"; //$NON-NLS-1$

    public static final String P_ID_CITY = "Address.City"; //$NON-NLS-1$

    public static final String P_ID_PROVINCE = "Address.Province"; //$NON-NLS-1$

    public static final String P_ID_POSTALCODE = "Address.PostalCode"; //$NON-NLS-1$

    //Property display keys
    public static final String P_STREET = MessageUtil.getString("Street"); //$NON-NLS-1$

    public static final String P_CITY = MessageUtil.getString("City"); //$NON-NLS-1$

    public static final String P_PROVINCE = MessageUtil.getString("Province"); //$NON-NLS-1$

    public static final String P_POSTALCODE = MessageUtil
            .getString("PostalCode"); //$NON-NLS-1$

    public static final String P_DESCRIPTORS = "properties"; //$NON-NLS-1$

    //default values	
    private static final StreetAddress STREET_DEFAULT = new StreetAddress();

    private static final String CITY_DEFAULT = MessageUtil
            .getString("unspecified_city"); //$NON-NLS-1$

    private static final Integer PROVINCE_DEFAULT = new Integer(0);

    private static final String POSTALCODE_DEFAULT = "A1B2C3"; //$NON-NLS-1$

    //
    static private class ProvinceLabelProvider extends LabelProvider {
        public String getText(Object element) {
            String[] provinceValues = new String[] {
                    MessageUtil.getString("British_Columbia"), MessageUtil.getString("Alberta"), MessageUtil.getString("Saskatchewan"), MessageUtil.getString("Manitoba"), MessageUtil.getString("Ontario"), MessageUtil.getString("Quebec"), MessageUtil.getString("Newfoundland"), MessageUtil.getString("Prince_Edward_Island"), MessageUtil.getString("Nova_Scotia"), MessageUtil.getString("New_Brunswick"), MessageUtil.getString("Yukon"), MessageUtil.getString("North_West_Territories"), MessageUtil.getString("Nunavut") }; //$NON-NLS-13$ //$NON-NLS-12$ //$NON-NLS-11$ //$NON-NLS-10$ //$NON-NLS-9$ //$NON-NLS-8$ //$NON-NLS-7$ //$NON-NLS-6$ //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
            return provinceValues[((Integer) element).intValue()];
        }
    }

    //
    private static Vector descriptors;

    private static String[] provinceValues;
    static {
        descriptors = new Vector();
        provinceValues = new String[] {
                MessageUtil.getString("British_Columbia"), MessageUtil.getString("Alberta"), MessageUtil.getString("Saskatchewan"), MessageUtil.getString("Manitoba"), MessageUtil.getString("Ontario"), MessageUtil.getString("Quebec"), MessageUtil.getString("Newfoundland"), MessageUtil.getString("Prince_Edward_Island"), MessageUtil.getString("Nova_Scotia"), MessageUtil.getString("New_Brunswick"), MessageUtil.getString("Yukon"), MessageUtil.getString("North_West_Territories"), MessageUtil.getString("Nunavut") }; //$NON-NLS-13$ //$NON-NLS-12$ //$NON-NLS-11$ //$NON-NLS-10$ //$NON-NLS-9$ //$NON-NLS-8$ //$NON-NLS-7$ //$NON-NLS-6$ //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
        descriptors.addElement(new PropertyDescriptor(P_ID_STREET, P_STREET));
        descriptors.addElement(new TextPropertyDescriptor(P_ID_CITY, P_CITY));

        //PostalCode
        PropertyDescriptor propertyDescriptor = new TextPropertyDescriptor(
                P_ID_POSTALCODE, P_POSTALCODE);
        //add custom validator to propertyDescriptor limiting postalcode
        //values to XYXYXY, where X is a letter and Y is a digit
        propertyDescriptor.setValidator(new ICellEditorValidator() {
            public String isValid(Object value) {
                if (value == null)
                    return MessageUtil.getString("postal_code_is_incomplete"); //$NON-NLS-1$

                //
                String testPostalCode = ((String) value).toUpperCase();
                final int length = testPostalCode.length();
                final char space = ' ';

                //removes white space
                StringBuffer postalCodeBuffer = new StringBuffer(6);
                char current;
                for (int i = 0; i < length; i++) {
                    current = testPostalCode.charAt(i);
                    if (current != space)
                        postalCodeBuffer.append(current);
                }
                testPostalCode = postalCodeBuffer.toString();

                //check for proper length
                if (testPostalCode.length() != 6) {
                    return MessageUtil.getString("postal_code_is_incomplete"); //$NON-NLS-1$
                }

                //check for proper format
                if (testPostalCode.charAt(1) < '0'
                        || testPostalCode.charAt(1) > '9'
                        || testPostalCode.charAt(3) < '0'
                        || testPostalCode.charAt(3) > '9'
                        || testPostalCode.charAt(5) < '0'
                        || testPostalCode.charAt(5) > '9'
                        || testPostalCode.charAt(0) < 'A'
                        || testPostalCode.charAt(0) > 'Z'
                        || testPostalCode.charAt(2) < 'A'
                        || testPostalCode.charAt(2) > 'Z'
                        || testPostalCode.charAt(4) < 'A'
                        || testPostalCode.charAt(4) > 'Z') {
                    //fail
                    return MessageUtil
                            .format(
                                    "_is_an_invalid_format_for_a_postal_code", new Object[] { testPostalCode }); //$NON-NLS-1$
                }

                //all pass
                return null;
            }
        });
        descriptors.addElement(propertyDescriptor);

        //
        ComboBoxPropertyDescriptor desc = new ComboBoxPropertyDescriptor(
                P_ID_PROVINCE, P_PROVINCE, provinceValues);
        desc.setLabelProvider(new ProvinceLabelProvider());
        descriptors.addElement(desc);
    }

    /**
     * Address Default Constructor
     */
    Address() {
        super();
    }

    /**
     * Creates a new address.
     *
     * @param street the street 
     * @param city the city
     * @param province the province
     * @param postalCode has the form XYXYXY: where X is a letter and Y is a digit
     * @exception IllegalArgumentException, if postalcode not in above form
     */
    public Address(StreetAddress street, String city, Integer province,
            String postalCode) {
        super();
        setStreet(street);
        setCity(city);
        setPostalCode(postalCode);
        setProvince(province);
    }

    /**
     * Returns the city
     */
    private String getCity() {
        if (city == null)
            city = CITY_DEFAULT;
        return city;
    }

    /* 
     * Standard Accessor
     */
    private static Vector getDescriptors() {
        return descriptors;
    }

    /* (non-Javadoc)
     * Method declared on IPropertySource
     */
    public Object getEditableValue() {
        return this.toString();
    }

    /**
     * Returns the postal code
     */
    private String getPostalCode() {
        if (postalCode == null)
            postalCode = POSTALCODE_DEFAULT;
        return postalCode;
    }

    /* (non-Javadoc)
     * Method declared on IPropertySource
     */
    public IPropertyDescriptor[] getPropertyDescriptors() {
        return (IPropertyDescriptor[]) getDescriptors().toArray(
                new IPropertyDescriptor[getDescriptors().size()]);
    }

    /** 
     * The <code>Address</code> implementation of this
     * <code>IPropertySource</code> method returns the following properties
     *
     * 	1) P_CITY returns java.lang.String
     * 	2) P_POSTALCODE returns java.lang.String
     *  3) P_PROVINCE returns java.lang.String
     *	4) P_STREET returns StreetAddress
     */
    public Object getPropertyValue(Object propKey) {
        if (propKey.equals(P_ID_PROVINCE))
            return getProvince();
        if (propKey.equals(P_ID_STREET))
            return getStreet();
        if (propKey.equals(P_ID_CITY))
            return getCity();
        if (propKey.equals(P_ID_POSTALCODE))
            return getPostalCode();
        return null;
    }

    /**
     * Returns the province
     */
    private Integer getProvince() {
        if (province == null)
            province = PROVINCE_DEFAULT;
        return province;
    }

    /**
     * Returns the street
     */
    public StreetAddress getStreet() {
        if (street == null)
            street = new StreetAddress();
        return street;
    }

    /* (non-Javadoc)
     * Method declared on IPropertySource
     */
    public boolean isPropertySet(Object property) {
        if (property.equals(P_ID_PROVINCE))
            return getProvince() != PROVINCE_DEFAULT;
        if (property.equals(P_ID_STREET))
            return !STREET_DEFAULT.equals(getStreet());
        if (property.equals(P_ID_CITY))
            return getCity() != CITY_DEFAULT;
        if (property.equals(P_ID_POSTALCODE))
            return getPostalCode() != POSTALCODE_DEFAULT;
        return false;
    }

    /* (non-Javadoc)
     * Method declared on IPropertySource
     */
    public void resetPropertyValue(Object property) {
        if (P_ID_POSTALCODE.equals(property)) {
            setPostalCode(POSTALCODE_DEFAULT);
            return;
        }
        if (P_ID_CITY.equals(property)) {
            setCity(CITY_DEFAULT);
            return;
        }
        if (P_ID_PROVINCE.equals(property)) {
            setProvince(PROVINCE_DEFAULT);
            return;
        }
        if (P_ID_STREET.equals(property)) {
            setStreet(new StreetAddress());
            return;
        }
    }

    /**
     * Sets the city
     */
    private void setCity(String newCity) {
        city = newCity;
    }

    /**
     * Sets the postal code
     */
    private void setPostalCode(String newPostalCode) {
        //validation in ICellEditorValidator registered in PropertyDescriptor
        this.postalCode = newPostalCode.toUpperCase();
    }

    /** 
     * The <code>Address</code> implementation of this
     * <code>IPropertySource</code> method 
     * defines the following Setable properties
     *
     * 	1) P_CITY expects java.lang.String
     * 	2) P_POSTALCODE expects java.lang.String
     *  3) P_PROVINCE expects java.lang.String
     * 
     * <p>P_ID_STREET is not set here since it is referenced 
     * and set directly in StreetAddress.
     * According to IPropertySource, StreetAddress.getEditableValue
     * should return a String which will be passed to this method  
     * as the value. A new StreetAddress object should then be 
     * created from the string. 
     * An alternative would be to return the StreetAddress 
     * directly in StreetAddress.getEditableValue and define a 
     * cell editor for the StreetAddress property.
     * This was ommitted for the sake of simplicity. 
     */
    public void setPropertyValue(Object name, Object value) {
        if (P_ID_POSTALCODE.equals(name)) {
            setPostalCode((String) value);
            return;
        }
        if (P_ID_CITY.equals(name)) {
            setCity((String) value);
            return;
        }
        if (P_ID_PROVINCE.equals(name)) {
            setProvince((Integer) value);
            return;
        }
    }

    /**
     * Sets the province
     */
    private void setProvince(Integer newProvince) {
        province = newProvince;
    }

    /**
     * Sets the street
     */
    private void setStreet(StreetAddress newStreet) {
        street = newStreet;
    }

    /**
     * The value as displayed in the Property Sheet.
     * @return java.lang.String
     */
    public String toString() {
        StringBuffer outStringBuffer = new StringBuffer();
        final String comma_space = ", "; //$NON-NLS-1$
        final String space = " "; //$NON-NLS-1$
        if (!getStreet().equals(STREET_DEFAULT)) {
            outStringBuffer.append(getStreet());
            outStringBuffer.append(comma_space);
        }

        outStringBuffer.append(getCity());
        outStringBuffer.append(space);
        outStringBuffer.append(provinceValues[getProvince().intValue()]);
        outStringBuffer.append(comma_space);
        outStringBuffer.append(getPostalCode());

        return outStringBuffer.toString();
    }
}