
import java.util.*;
import java.awt.*;

import se.datadosen.jalbum.JAFilter;
import se.datadosen.util.*;

public class BPPFilterProperties extends Properties
{
	private static final String KEY_FILTER_CLASS = "class";
	public static final String STYLE_BACKGROUND_FILE = "$styleBackgroundFile";
	private static final String STYLE_BACKGROUND_COLOR = "$styleBackgroundColor";
	private static final String STYLE_NEGATIVE_BACKGROUND_COLOR = "$styleNegativeBackgroundColor";
	private static final String STYLE_FOREGROUND_COLOR = "$styleForegroundColor";
	private static final String STYLE_NEGATIVE_FOREGROUND_COLOR = "$styleNegativeForegroundColor";
	public static final String FILTER_BACKGROUND_FILE_ATTRIBUTE_NAME = "bgFile";

	private JAFilter filter = null;
	private Properties dynamicProps = null;
	private Properties oldPropValues = null;
	private String name;

	private String backgroundFile = null;
	private String backgroundColor = null;
	private String foregroundColor = null;

	public BPPFilterProperties(String name)
	{
		this.name = name;
	}

	public String getName()
	{
		return name;
	}

	public JAFilter createFilter() throws ClassNotFoundException, IllegalAccessException, InstantiationException, BeanBinderException
	{
		if( filter!=null )
			return filter;

		String filterClass = getProperty(KEY_FILTER_CLASS);

		if( filterClass==null || filterClass.trim().equals("") )
			return null;

		filter = (JAFilter) getClass().getClassLoader().loadClass(filterClass).newInstance();

		Iterator it = entrySet().iterator();
		Properties staticProps = new Properties();

		while( it.hasNext() )
		{
			Map.Entry entry = (Map.Entry) it.next();

			if( entry.getValue()!=null )
			{
				if( entry.getKey().equals(KEY_FILTER_CLASS) )
					continue;
				if( entry.getValue().equals(STYLE_BACKGROUND_FILE) || entry.getValue().equals(STYLE_BACKGROUND_COLOR) ||
					entry.getValue().equals(STYLE_FOREGROUND_COLOR) || entry.getValue().equals(STYLE_NEGATIVE_BACKGROUND_COLOR) ||
					entry.getValue().equals(STYLE_NEGATIVE_FOREGROUND_COLOR) )
				{
					if( dynamicProps==null )
					{
						dynamicProps = new Properties();
						oldPropValues = new Properties();
					}
					dynamicProps.put(entry.getKey(), entry.getValue());
					continue;
				}
			}
			staticProps.put(entry.getKey(), entry.getValue());
		}

		BeanBinder.setProperties(filter, staticProps);
		return filter;
	}

	public JAFilter getFilter()
	{
		return filter;
	}

	public void resetDynamicAttributes()
	{
		backgroundColor = null;
		backgroundFile = null;
		foregroundColor = null;
	}

	public void applyDynamicAttributes() throws BeanBinderException
	{
		if( dynamicProps==null )
			return;

		Properties props = new Properties();
		Iterator it = dynamicProps.entrySet().iterator();

		while( it.hasNext() )
		{
			Map.Entry entry = (Map.Entry) it.next();
			String value = null;

			if( entry.getValue().equals(STYLE_BACKGROUND_COLOR) )
				value = backgroundColor;
			else if( entry.getValue().equals(STYLE_NEGATIVE_BACKGROUND_COLOR) )
			{
				Color color = Colors.getHTMLColor(backgroundColor);

				value = "#" + negateChannel(color.getRed()) + negateChannel(color.getGreen()) + negateChannel(color.getBlue());
			}
			else if( entry.getValue().equals(STYLE_BACKGROUND_FILE) )
				value = backgroundFile;
			else if( entry.getValue().equals(STYLE_FOREGROUND_COLOR) )
				value = foregroundColor;
			else if( entry.getValue().equals(STYLE_NEGATIVE_FOREGROUND_COLOR) )
			{
				Color color = Colors.getHTMLColor(foregroundColor);

				value = "#" + negateChannel(color.getRed()) + negateChannel(color.getGreen()) + negateChannel(color.getBlue());
			}

			if( !oldPropValues.containsKey(entry.getKey()) || !oldPropValues.get(entry.getKey()).equals(value) )
				props.put(entry.getKey(), value);
		}

		if( !props.isEmpty() )
		{
			BeanBinder.setProperties(filter, props);
			oldPropValues.putAll(props);
		}
	}

	private String negateChannel(int channel)
	{
		String result = Integer.toHexString(255 - channel);

		if( result.length()==2 )
			return result;
		else
			return "0" + result;
	}

	public void setBackgroundFile(String backgroundFile)
	{
		this.backgroundFile = backgroundFile;
	}

	public void setBackgroundColor(String backgroundColor)
	{
		this.backgroundColor = backgroundColor;
	}

	public void setForegroundColor(String foregroundColor)
	{
		this.foregroundColor = foregroundColor;
	}

	public boolean needStyleSheetBackgroundColor()
	{
		return needStyleSheetDynamicValue(STYLE_BACKGROUND_COLOR) || needStyleSheetDynamicValue(STYLE_NEGATIVE_BACKGROUND_COLOR);
	}

	public boolean needStyleSheetBackgroundFile()
	{
		return needStyleSheetDynamicValue(STYLE_BACKGROUND_FILE);
	}

	public boolean needStyleSheetForegroundColor()
	{
		return needStyleSheetDynamicValue(STYLE_FOREGROUND_COLOR) || needStyleSheetDynamicValue(STYLE_NEGATIVE_FOREGROUND_COLOR);
	}

	private boolean needStyleSheetDynamicValue(String dynamicValue)
	{
		if( dynamicProps==null )
			return false;

		Iterator it = dynamicProps.values().iterator();

		while( it.hasNext() )
		{
			String value = (String) it.next();

			if( value!=null && value.equals(dynamicValue) )
				return true;
		}
		return false;
	}
}
