////////////////////////////////////////////////////////////////////////////////
//
//  ADOBE SYSTEMS INCORPORATED
//  Copyright 2006-2007 Adobe Systems Incorporated
//  All Rights Reserved.
//
//  NOTICE: Adobe permits you to use, modify, and distribute this file
//  in accordance with the terms of the license agreement accompanying it.
//
////////////////////////////////////////////////////////////////////////////////

package flex.ant;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DynamicAttribute;
import org.apache.tools.ant.Task;

public final class HtmlWrapperTask extends Task implements DynamicAttribute
{
	private static final int CLIENT_SIDE_DETECTION = 0;
	private static final int EXPRESS_INSTALLATION = 1;
	private static final int NO_PLAYER_DETECTION = 2;

	private static final String[] templates = new String[] {"client-side-detection",
															"express-installation",
															"no-player-detection"};

	private static final String TEMPLATE_DIR = "/templates/";
	private static final String WITH_HISTORY = "-with-history/";
	private static final String INDEX_TEMPLATE_HTML = "index.template.html";
	private static final String AC_OETAGS_JS = "AC_OETags.js";
	private static final String HISTORY_CSS = "history/history.css";
	private static final String HISTORY_JS = "history/history.js";
	private static final String HISTORY_FRAME_HTML = "history/historyFrame.html";
	private static final String PLAYERPRODUCTINSTALL_SWF = "playerProductInstall.swf";

	private String application;
	private String bgcolor = "white";
	private String fileName = "index.html";
	private String height = "400";
	private String output;
	private String swf;
	private String title = "Flex Application";
	private String versionMajor = "9";
	private String versionMinor = "0";
	private String versionRevision = "0";
	private String width = "400";
	private boolean history = false;
	private int template;
	
	private String sdkHome = "";

	public HtmlWrapperTask()
	{
		setTaskName("html-wrapper");
	}

	public void execute() throws BuildException
	{
		// Check for requirements.
		if (swf == null)
		{
			throw new BuildException("The <html-wrapper> task requires the 'swf' attribute.", getLocation());
		}

		InputStream inputStream = getInputStream();

		if (inputStream != null)
		{
			BufferedReader bufferedReader = null;
			PrintWriter printWriter = null;
			String path = null;

			try
			{
				bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

				if (output != null)
				{
					File outputDir = new File(output);
					if (outputDir.exists() && outputDir.isDirectory())
					{
						path = output + File.separatorChar + fileName;
					}
					else
					{
						String base = getProject().getBaseDir().getAbsolutePath();
						outputDir = new File(base + File.separatorChar + output);
						if (outputDir.exists() && outputDir.isDirectory())
						{
							path = base + File.separatorChar + output + File.separatorChar + fileName;
						}
						else
						{
							throw new BuildException("output directory does not exist: " + output);
						}
					}
				}
				else
				{
					path = fileName;
				}

				printWriter = new PrintWriter(new FileWriter(path));

				String line;

				while ((line = bufferedReader.readLine()) != null)
				{
					printWriter.println(substitute(line));
				}
			}
			catch (IOException ioException)
			{
				System.err.println("Error outputting resource: " + path);
				ioException.printStackTrace();
			}
			finally
			{
				try
				{
					bufferedReader.close();
					printWriter.close();
				}
				catch (Exception exception)
				{
				}
			}
		}
		else
		{
			throw new BuildException("Missing resources", getLocation());
		}
	}

	private InputStream getInputStream()
	{
		InputStream inputStream = null;
		
		try {
			switch (template)
			{
				case CLIENT_SIDE_DETECTION:
				{
					if (history)
					{
						inputStream = new FileInputStream(sdkHome + TEMPLATE_DIR + templates[0] +
																	 WITH_HISTORY + INDEX_TEMPLATE_HTML);
						outputResources(sdkHome + TEMPLATE_DIR + templates[0] + WITH_HISTORY, 
										new String[] {AC_OETAGS_JS, HISTORY_FRAME_HTML, HISTORY_JS, HISTORY_CSS});
					}
					else
					{
						inputStream = new FileInputStream(sdkHome + TEMPLATE_DIR + templates[0] + "/" +
																	 INDEX_TEMPLATE_HTML);
						outputResources(sdkHome + TEMPLATE_DIR + templates[0] + "/", new String[] {AC_OETAGS_JS});
					}
					break;
				}
				case EXPRESS_INSTALLATION:
				default:
				{
					if (history)
					{
						inputStream = new FileInputStream(sdkHome + TEMPLATE_DIR + templates[1] +
																	 WITH_HISTORY + INDEX_TEMPLATE_HTML);
						outputResources(sdkHome + TEMPLATE_DIR + templates[1] + WITH_HISTORY, 
										new String[] {AC_OETAGS_JS, HISTORY_FRAME_HTML, HISTORY_JS,
													  HISTORY_CSS, PLAYERPRODUCTINSTALL_SWF});
					}
					else
					{
						inputStream = new FileInputStream(sdkHome + TEMPLATE_DIR + templates[1] + "/" +
																	 INDEX_TEMPLATE_HTML);
						outputResources(sdkHome + TEMPLATE_DIR + templates[1] + "/",
										new String[] {AC_OETAGS_JS, PLAYERPRODUCTINSTALL_SWF});
					}
					break;
				}
				case NO_PLAYER_DETECTION:
				{
					if (history)
					{
						inputStream = new FileInputStream(sdkHome + TEMPLATE_DIR + templates[2] +
																	 WITH_HISTORY + INDEX_TEMPLATE_HTML);
						outputResources(sdkHome + TEMPLATE_DIR + templates[2] + WITH_HISTORY, 
										new String[] {AC_OETAGS_JS, HISTORY_FRAME_HTML, HISTORY_JS, HISTORY_CSS});
					}
					else
					{
						inputStream = new FileInputStream(sdkHome + TEMPLATE_DIR + templates[2] + "/" +
																	 INDEX_TEMPLATE_HTML);
						outputResources(sdkHome + TEMPLATE_DIR + templates[2] + "/", new String[] {AC_OETAGS_JS});
					}
					break;
				}
			}
		} catch (java.io.FileNotFoundException fnfe) {
			throw new BuildException(fnfe);
		}

		return inputStream;
	}

	private void outputResources(String resourceDir, String[] resources)
	{
		BufferedReader bufferedReader = null;
		PrintWriter printWriter = null;

		for (int i = 0; i < resources.length; i++)
		{
			try
			{
				InputStream inputStream = new FileInputStream(resourceDir + resources[i]);
				bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
				String path = null;

				if (output != null)
				{
					File outputDir = new File(output);
					if (outputDir.exists() && outputDir.isDirectory())
					{
						path = output + File.separatorChar + resources[i];
					}
					else
					{
						String base = getProject().getBaseDir().getAbsolutePath();
						outputDir = new File(base + File.separatorChar + output);
						if (outputDir.exists() && outputDir.isDirectory())
						{
							path = base + File.separatorChar + output + File.separatorChar + resources[i];
						}
						else
						{
							throw new BuildException("output directory does not exist: " + output);
						}
					}
				}
				else
				{
					path = resources[i];
				}

				File file = new File(path);
				file.getParentFile().mkdirs();

				printWriter = new PrintWriter(new FileWriter(file));
				
				String line;

				while ((line = bufferedReader.readLine()) != null)
				{
					printWriter.println(line);
				}
			}
			catch (IOException ioException)
			{
				System.err.println("Error outputting resource: " + resources[i]);
				ioException.printStackTrace();
			}
			finally
			{
				try
				{
					bufferedReader.close();
					printWriter.close();
				}
				catch (Exception exception)
				{
				}
			}
		}
	}

	public void setApplication(String application)
	{
		this.application = application;
	}

	public void setBgcolor(String bgcolor)
	{
		this.bgcolor = bgcolor;
	}

	public void setDynamicAttribute(String name, String value)
	{
		if (name.equals("version-major"))
		{
			versionMajor = value;
		}
		else if (name.equals("version-minor"))
		{
			versionMinor = value;
		}
		else if (name.equals("version-revision"))
		{
			versionRevision = value;
		}
		else
		{
			throw new BuildException("The <html-wrapper> task doesn't support the \""
									 + name + "\" attribute.", getLocation());
		}
	}

	public void setFile(String fileName)
	{
		this.fileName = fileName;
	}

	public void setHeight(String height)
	{
		this.height = height;
	}

	public void setHistory(boolean history)
	{
		this.history = history;
	}

	public void setOutput(String output)
	{
		this.output = output;
	}

	public void setSwf(String swf)
	{
		// Doctor up backslashes to fix bug 193739.
		this.swf = swf.replace('\\', '/');
		if (application == null)
		{
			application = this.swf;
		}
	}
	
	public void setSdkHome(String sdkHome) {
		this.sdkHome = sdkHome;
	}

	public void setTemplate(String template)
	{
		if (template.equals(templates[0]))
		{
			this.template = CLIENT_SIDE_DETECTION;
		}
		else if (template.equals(templates[1]))
		{
			this.template = EXPRESS_INSTALLATION;
		}
		else if (template.equals(templates[2]))
		{
			this.template = NO_PLAYER_DETECTION;
		}
		else
		{
			throw new BuildException("The 'template' attribute must be one of '" +
									 templates[0] + "', '" +
									 templates[1] + "', '" +
									 templates[2] + "'.", getLocation());
		}
	}

	public void setTitle(String title)
	{
		this.title = title;
	}

	public void setWidth(String width)
	{
		this.width = width;
	}

	private String substitute(String input)
	{
		String result = input.replaceAll("\\$\\{application\\}", application);
		result = result.replaceAll("\\$\\{bgcolor\\}", bgcolor);
		result = result.replaceAll("\\$\\{height\\}", height);
		result = result.replaceAll("\\$\\{swf\\}", swf);
		result = result.replaceAll("\\$\\{title\\}", title);
		result = result.replaceAll("\\$\\{version_major\\}", versionMajor);
		result = result.replaceAll("\\$\\{version_minor\\}", versionMinor);
		result = result.replaceAll("\\$\\{version_revision\\}", versionRevision);
		result = result.replaceAll("\\$\\{width\\}", width);
		return result;
	}
}

