/*
 *  ChangeShape.java
 *  Cookbook
 *
 *  Copyright (c) 2001-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 java.util.*;

/*
 * This example shows how to morph a shape:
 *
 * To run this example, type the following on a command line:
 *
 *     java -cp cookbook.jar ChangeShape file-out
 *
 * where
 *
 *     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.
*/
public class ChangeShape
{
    public static void main(String[] args)
    {
        try
        {
            String out = args.length == 0 ? "ChangeShape.swf" : args[0];
            ChangeShape example = new ChangeShape();         
            FSMovie movie = new FSMovie();            
            example.createMovie(movie);
            movie.encodeToFile(out);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    
    void createMovie(FSMovie movie)
    {
        movie.setFrameRate(12.0f);
        movie.setFrameSize(new FSBounds(0, 0, 8000, 8000));
        movie.add(new FSSetBackgroundColor(FSColorTable.lightblue()));
        
        FSShape rectangle = createRectangle(movie);
        FSShape circle = createCircle(movie);
        
        FSBounds startBounds = new FSBounds(-2000, -2000, 2000, 2000);
        FSBounds endBounds = new FSBounds(-2000, -2000, 2000, 2000);
        
        ArrayList lineStyles = new ArrayList();
        ArrayList fillStyles = new ArrayList();
        
        lineStyles.add(new FSMorphSolidLine(20, 20, FSColorTable.black(), FSColorTable.white()));
        fillStyles.add(new FSMorphSolidFill(FSColorTable.black(),FSColorTable.white()));

        FSDefineMorphShape shape = new FSDefineMorphShape(movie.newIdentifier(), 
                startBounds, endBounds, 
                fillStyles, lineStyles, 
                rectangle, circle);
        
        movie.add(shape);

        movie.add(new FSPlaceObject2(shape.getIdentifier(), 1, 0.0f, 4000, 4000));
        movie.add(new FSShowFrame());
    
        for (float i=0.0f; i<1.0; i+= 0.05)
        {
            movie.add(new FSPlaceObject2(1, i, 4000, 4000));
            movie.add(new FSShowFrame());
        } 

        // Add a delay so the circle is displayed for 1 second
        for (int i=0; i<12; i++) {
             movie.add(new FSShowFrame());
        } 
    }

    private FSShape createRectangle(FSMovie movie)
    {
        int width = 4000;
        int height = 4000;
        
        ArrayList lineStyles = new ArrayList();
        ArrayList fillStyles = new ArrayList();
        
        lineStyles.add(new FSMorphSolidLine(20, 20, FSColorTable.black(), FSColorTable.white()));
        fillStyles.add(new FSMorphSolidFill(FSColorTable.black(),FSColorTable.white()));
        
        /* 
         * Create the outline of the shape. Morphing requires that
         * both shapes have the same number of vertices.
         */
        ArrayList shapeRecords = new ArrayList();
        
        shapeRecords.add(new FSShapeStyle(1, 1, 0, width/2, 0));
        shapeRecords.add(new FSLine(0, height/2));
        shapeRecords.add(new FSLine(-width/2, 0));
        shapeRecords.add(new FSLine(-width/2, 0));
        shapeRecords.add(new FSLine(0, -height/2));
        shapeRecords.add(new FSShapeStyle(-width/2, 0));
        shapeRecords.add(new FSLine(0, -height/2));
        shapeRecords.add(new FSLine(width/2, 0));
        shapeRecords.add(new FSLine(width/2, 0));
        shapeRecords.add(new FSLine(0, height/2));
        
        return new FSShape(shapeRecords);
    }
    
    private FSShape createCircle(FSMovie movie)
    {
        int x = 0;
        int y = 0;

        int rx = 2000;
        int ry = 2000;
        
        int startX = (int) (0.707 * rx) + x;
        int startY = (int) (0.707 * ry) + y;

        int ax = (int) (0.293 * rx);
        int ay = (int) (0.293 * ry);
        int cx = (int) (0.414 * rx);
        int cy = (int) (0.414 * ry);
             
        /* 
         * Create the outline of the shape. Morphing requires that
         * both shapes have the same number of vertices.
         */
        ArrayList shapeRecords = new ArrayList();
        
        shapeRecords.add(new FSShapeStyle(1, 1, 0, startX, startY));
        shapeRecords.add(new FSCurve(-ax, ay, -cx, 0));
        shapeRecords.add(new FSCurve(-cx, 0, -ax, -ay));
        shapeRecords.add(new FSCurve(-ax, -ay, 0, -cy));
        shapeRecords.add(new FSCurve(0, -cy,  ax, -ay));
        shapeRecords.add(new FSCurve(ax, -ay, cx, 0));
        shapeRecords.add(new FSCurve(cx, 0,  ax, ay));
        shapeRecords.add(new FSCurve(ax, ay, 0, cy));
        shapeRecords.add(new FSCurve(0, cy, -ax, ay));
        
        return new FSShape(shapeRecords);
    }
}