
import se.datadosen.jalbum.*;
import se.datadosen.util.BeanBinderException;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.List;

public class BPPFilterGroup extends BPPStyleSheet implements JAFilter, ModifiesSize
{
	private List filterProperties = new LinkedList();
	private String name;
	private int applyLevel;

	public BPPFilterGroup(AlbumBean engine, String name, int applyLevel)
	{
		super(engine);
		this.name = name;
		this.applyLevel = applyLevel;
	}

	private File getCurrentFile(Map vars)
	{
		File[] files = (File[]) vars.get("files");
		if( files==null )
			return null;
		int imageNum = ((Integer) vars.get("imageNum")).intValue();

		return files[imageNum - 1];
	}

	private void prepareFilter(BPPFilterProperties filterProp, File dir)
	{
		filterProp.resetDynamicAttributes();

		if( filterProp.needStyleSheetBackgroundFile() )
		{
			try
			{
				File file = extractStyleSheetBackgroundImage( dir );

				filterProp.setBackgroundFile((file!=null && file.exists()) ? file.getAbsolutePath() : "");
			}
			catch( IOException e )
			{
				log("Error extracting the dynamic background file for the filter!", e);
			}
		}

		if( filterProp.needStyleSheetBackgroundColor() )
		{
			try
			{
				String color = extractStyleSheetBackgroundColor(dir, applyLevel);

				filterProp.setBackgroundColor( !isEmptyString(color) ? color : "white" );
			}
			catch( IOException e )
			{
				log("Error extracting the dynamic background color for the filter!", e);
			}
		}

		if( filterProp.needStyleSheetForegroundColor() )
		{
			try
			{
				String color = extractStyleSheetForegroundColor(dir);

				filterProp.setForegroundColor( !isEmptyString(color) ? color : "black" );
			}
			catch( IOException e )
			{
				log("Error extracting the dynamic foreground color for the filter!", e);
			}
		}

		try
		{
			filterProp.applyDynamicAttributes();
		}
		catch( BeanBinderException e )
		{
			log("Error applying the dynamic attributes to the filter!", e);
		}
	}

	private File extractStyleSheetBackgroundImage(File dir) throws IOException
	{
		File background = null;

		if( dir!=null )
		{
			if( applyLevel==BPPFrameHandler.APPLY_LEVEL_SLIDE || applyLevel==BPPFrameHandler.APPLY_LEVEL_MOVIE_SLIDE )
				background = getBackgroundImageFile(Constants.META_SLIDE_BACKGROUND_IMAGE, dir);

			if( background==null )
				background = getBackgroundImageFile(Constants.META_INDEX_BACKGROUND_IMAGE, dir);

			if( background!=null )
				return background;
		}

		return extractStyleSheetBackgroundImage(dir, applyLevel);
	}

	public void addFilter(BPPFilterProperties prop) throws Exception
	{
		JAFilter filter = prop.createFilter();

		if( filter==null )
		{
			log("No filter class defined for '" + prop.getName() + "'!");
			return;
		}

		filterProperties.add(prop);
	}

	public BufferedImage filter(BufferedImage bufferedImage, Map vars)
	{
		Iterator it = filterProperties.iterator();
		BufferedImage result = bufferedImage;
		File currentFile = getCurrentFile(vars);

		while( it.hasNext() )
		{
			BPPFilterProperties filterProp = (BPPFilterProperties) it.next();

			prepareFilter(filterProp, (currentFile!=null) ? currentFile.getParentFile() : null);
			result = filterProp.getFilter().filter(result, vars);
		}
		return result;
	}

	public Dimension getModifiedSize(Dimension dimension, Map vars)
	{
		Iterator it = filterProperties.iterator();
		Dimension result = dimension;
		File currentFile = getCurrentFile(vars);

		while( it.hasNext() )
		{
			BPPFilterProperties filterProp = (BPPFilterProperties) it.next();

			if( filterProp.getFilter() instanceof ModifiesSize )
			{
				prepareFilter(filterProp, (currentFile!=null) ? currentFile.getParentFile() : null);
				result = ((ModifiesSize) filterProp.getFilter()).getModifiedSize(result, vars);
			}
		}
		return result;
	}

	public String getDescription()
	{
		return "Filter Group";
	}

	public String getName()
	{
		return name;
	}
}
