/*
* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: 
*
*/


//package com.nokia.sdt.symbian.ui.editors;
package com.nokia.sdt.symbian.ui.editors;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.viewers.ICellEditorValidator;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.ui.views.properties.IPropertySource;


import com.nokia.sdt.datamodel.util.ModelUtils;
import com.nokia.sdt.displaymodel.IDisplayModel;
import com.nokia.sdt.displaymodel.ILookAndFeel;
import com.nokia.sdt.symbian.ui.UIPlugin;
import com.nokia.cpp.internal.api.utils.core.TextUtils;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.swt.graphics.*;

import java.util.*;
import java.util.regex.Pattern;

public class PaletteEntryArrayEditorFactory extends AbstractArrayPropertyEditorFactory {

	static Pattern rgbPattern = Pattern.compile(","); //$NON-NLS-1$
	private static final String BUNDLE_NAME = "com.nokia.sdt.symbian.ui.editors.SystemColors"; //$NON-NLS-1$	
	
	static HashMap sysColorToLocalized;
	static HashMap localizedToSysColor;
	static String noneDisplayString;
	static final String noneValue = ""; //$NON-NLS-1$

	private static void initSysColorMaps() {
		if (sysColorToLocalized == null) {
			sysColorToLocalized = new HashMap();
			localizedToSysColor = new HashMap();
			ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_NAME);
			Enumeration keys = bundle.getKeys();
			while (keys.hasMoreElements()) {
				String sysColor = (String) keys.nextElement();
				String localized = bundle.getString(sysColor);
				sysColorToLocalized.put(sysColor, localized);
				localizedToSysColor.put(localized, sysColor);
			}
			noneDisplayString = Messages.getString("PaletteEntryEditorFactory.1"); //$NON-NLS-1$
		}
	}
	private static final int DEFAULT_EXTENT = 16;
	  /**
	   * Creates and returns the color image data for the given control
	   * and RGB value. The image's size is either the control's item extent 
	   * or the cell editor's default extent, which is 16 pixels square.
	   *
	   * @param color the color
	   */

	private static ImageData createColorImage(RGB color, boolean transparentOnly) {

        int vsize = 10;
        int hsize = 16;
        int indent = 2;
        int extent = DEFAULT_EXTENT;
    
        int width = indent + hsize;
        int height = extent;

        int xoffset = indent;
        int yoffset = (height - vsize) / 2;

        RGB black = new RGB(0, 0, 0);
        PaletteData dataPalette = new PaletteData(new RGB[] { black, black,
                color });
        ImageData data = new ImageData(width, height, 4, dataPalette);
        data.transparentPixel = 0;
        if (!transparentOnly) {
	        int vend = vsize - 1;
	        int hend = hsize - 1;
	        for (int y = 0; y < vsize; y++) {
	            for (int x = 0; x < hsize; x++) {
	                if (x == 0 || y == 0 || x == hend || y == vend)
	                    data.setPixel(x + xoffset, y + yoffset, 1);
	                else
	                    data.setPixel(x + xoffset, y + yoffset, 2);
	            }
	        }
        }
        return data;
    }
    
    private static Image makeRGBImage(RGB value, boolean transparentOnly) {
		ImageData id = createColorImage(value, transparentOnly);
		ImageData mask = id.getTransparencyMask();
		Image result = new Image(null, id, mask);
		return result;
    }

	static RGB valueAsRGB(Object value, ILookAndFeel laf) {
		RGB result = null;
		if (value instanceof String) {
			// This implementation allows only decimal values
			// from 0-255 for each component.
			String[] split = rgbPattern.split(value.toString());
			if (split != null && split.length == 3) {
				int red = TextUtils.parseInt(split[0], -1);
				int green = TextUtils.parseInt(split[1], -1);
				int blue = TextUtils.parseInt(split[2], -1);
				try {
					// throws if a component is <0 or >255
					result = new RGB(red, green, blue);
				}
				catch (IllegalArgumentException x) {
				}
			}
			else if (laf != null){
				// check if a system color
				Color color =  laf.getColor((String)value);
				if (color != null) {
					result = color.getRGB();
				}
			}
		}
		return result;
	}
	
	static String rgbAsText(RGB value) {
		if (value == null) return null;
		StringBuffer buf = new StringBuffer();
		buf.append(Integer.toString(value.red));
		buf.append(","); //$NON-NLS-1$
		buf.append(Integer.toString(value.green));
		buf.append(","); //$NON-NLS-1$
		buf.append(Integer.toString(value.blue));
		return buf.toString();
	}
	
	class PaletteEntryLabelProvider extends LabelProvider {

    	private ILookAndFeel laf;
    	private Image lastImage;
    	private Image sysColorImage;
    	
    	PaletteEntryLabelProvider(EObject object) throws CoreException {
    		initSysColorMaps();
    		
    		IDisplayModel displayModel = ModelUtils.getDisplayModel(object);
    		if (displayModel != null) {
    			laf = displayModel.getLookAndFeel();
    		}
    		
    		if (sysColorImage == null) {
    			sysColorImage = makeRGBImage(new RGB(255, 255, 255), true);
    		}
    	}
    	
		public void dispose() {
			if (lastImage != null) {
				lastImage.dispose();
				lastImage = null;
			}
			super.dispose();
		}
		
	    public Image getImage(Object element) {
	    	Image ColorImage;
	    	ColorImage = makeRGBImage(new RGB(255, 255, 255), true);
	    	return ColorImage;
	    	}

	    public String getText(Object element) {
	    	IPropertySource palettePropertySource = (IPropertySource) element;
	    	return palettePropertySource.getPropertyValue("label").toString(); //$NON-NLS-1$
	    	}
	}

	   static class PaletteEntryCellEditorValidator implements ICellEditorValidator {
	    	
	    	PaletteEntryCellEditorValidator() {
	    		initSysColorMaps();
	    	}

			public String isValid(Object value) {
				boolean valid = localizedToSysColor.containsKey(value);
				if (!valid)
					valid = (value instanceof String) && ((String)value).length() == 0;
				if (!valid)
					valid = valueAsRGB(value, null) != null;
				String result = null;
				if (!valid) {
					result = Messages.getString("PaletteEntryEditorFactory.3"); //$NON-NLS-1$
				}
				return result;
			}
	    	
	    }

	public ICellEditorValidator createCellEditorValidator(EObject object, String propertyId) {
		return new PaletteEntryCellEditorValidator();
	}

	//@Override
	public ILabelProvider createElementLabelProvider(final EObject object, Object propertyID) {

		ILabelProvider result = null;
		try {
			result = new PaletteEntryLabelProvider(object);
//			result = new RGBLabelProvider(object);
		}
		catch (CoreException x) {
			UIPlugin.log(x);
			throw new RuntimeException(x);
		}
		return result;
		
		
	}

	
	@Override
	protected boolean isFixedLengthArrayProperty(EObject object, Object propertyID) {
		return false;
	}
}
