/*
 *  BasicScript.java
 *  Cookbook
 *
 *  Copyright (c) 2004-2009 Flagstone Software Ltd. All rights reserved.
 *
 *  This code is distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 *  EXPRESS OR IMPLIED, AND Flagstone HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING
 *  WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 *  PURPOSE, AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
 */

import com.flagstone.transform.*;
import com.flagstone.translate.*;

import java.io.*;
import java.util.*;

/* This example shows how to use Translate to compile ActionScript to control a 
 * movie clip.
 *
 * To run this example, type the following on a command line:
 *
 *     java -cp cookbook.jar BasicScript script-file file-out
 *
 * where
 *
 *     script-file is a file containing the ActionScript that will be executed to 
 *     control the movie clip.
 * 
 *     file-out is the path where the file will be written. If no output file 
 *     is specified then a file named after the example will be written to the 
 *     current directory.
 *
 * IMPORTANT: When running the movie generated by the example in Internet Explorer, 
 * you will need to click on the browser window so the Flash plug-in gets the keyboard
 * focus.
 */
public class BasicScript
{
    public static void main(String[] args)
    {
        try
        {
        	String out = args.length == 1 ? "BasicScript.swf" : args[1];
        	BasicScript example = new BasicScript();         
            FSMovie movie = new FSMovie();            
            example.createMovie(movie, args[0]);
            movie.encodeToFile(out);
        }
        catch (Exception e)
        {
        	e.printStackTrace();
        }
    }

    public void createMovie(FSMovie movie, String filename) throws ParseException, IOException
    {
        int screenWidth = 8000;
        int screenHeight = 8000;
        
        ASParser parser = new ASParser();
        
        /*
         * The movie clip is the simplest possible - just a simple rectangle displayed
         * for a single frame.
         */
        FSDefineShape rectangle = rectangle(movie.newIdentifier(), 2000, 2000, FSColorTable.red());
        FSDefineMovieClip clip = new FSDefineMovieClip(movie.newIdentifier());
        
        clip.add(new FSPlaceObject2(rectangle.getIdentifier(), 1, 0, 0));
        clip.add(new FSShowFrame());
        
        /*
         * Now generate the encoded array of FSClipEvent objects from the script and 
         * add it to the object used to place the movie clip on the screen.
         * 
         * The version number of Flash to encode to is required as the format of the 
         * data structures holding the event information for a movie clip changed with
         * the releases of Flash 6 and Flash 7.
         */
        String script = contentsOfFile(filename);
        
        byte[] events = parser.parse(script).encode(movie.getVersion());

        FSPlaceObject2 location = new FSPlaceObject2(clip.getIdentifier(), 1, events, "clip", 
                screenWidth/2, screenHeight/2);
        
        /*
         * Put all the objects together in a movie.
         */
        movie.setFrameRate(12.0f);
        movie.setFrameSize(new FSBounds(0, 0, screenWidth, screenHeight));
        movie.add(new FSSetBackgroundColor(FSColorTable.lightblue()));
        movie.add(rectangle);
        movie.add(clip);
        movie.add(location);
        movie.add(new FSShowFrame());
    }
    
    /* Defines a simple rectangle filled with a solid colour.
     * 
     * @param identifier the unique identifier used to reference the shape definition.
     * @param width the width of the rectangle in twips.
     * @param height the height of the rectangle in twips.
     * @param color the colour used to fill the contents of the rectangle.
     */
    private FSDefineShape rectangle(int identifier, int width, int height, FSColor color)
    {
        FSBounds bounds = new FSBounds(-width/2, -height/2, width/2, height/2);
        
        ArrayList lineStyles = new ArrayList();
        ArrayList fillStyles = new ArrayList();
        
        lineStyles.add(new FSSolidLine(20, FSColorTable.black()));
        fillStyles.add(new FSSolidFill(color));
        
        ArrayList shapeRecords = new ArrayList();
        
        shapeRecords.add(new FSShapeStyle(1, 1, 0, -width/2, -height/2));
        shapeRecords.add(new FSLine(width, 0));
        shapeRecords.add(new FSLine(0, height));
        shapeRecords.add(new FSLine(-width, 0));
        shapeRecords.add(new FSLine(0, -height));
        
        return new FSDefineShape(identifier, bounds, fillStyles, lineStyles, new FSShape(shapeRecords));
    } 
    
    /* 
     * Returns the contents of the file as a single string.
     * 
     * @param fileName the name of the file to read.
     * 
     * @return a String containing the contents of the file.
     * 
     * @throws FileNotFoundException if the file could not be found.
     * @throws IOException if an error occurred while reading the file.
     */
    private String contentsOfFile(String fileName) throws FileNotFoundException, IOException
    {
        String script = "";

        File aFile = new File(fileName);

        if (aFile.exists())
        {
            byte[] fileIn = new byte[(int)aFile.length()];

            FileInputStream fileContents = new FileInputStream(aFile);
            fileContents.read(fileIn);

            script = new String(fileIn);

            fileContents.close();
        }
        else
        {
            throw new FileNotFoundException();
        } 
        return script;
    }

}