/*
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package flash.swf.tools;

import flash.util.Base64;
import flash.util.SwfImageUtils;
import flash.swf.Dictionary;
import flash.swf.Header;
import flash.swf.TagEncoder;
import flash.swf.TagHandler;
import flash.swf.TagValues;
import flash.swf.tags.DebugID;
import flash.swf.tags.DefineBits;
import flash.swf.tags.DefineShape;
import flash.swf.tags.DefineSprite;
import flash.swf.tags.DefineTag;
import flash.swf.tags.DoAction;
import flash.swf.tags.DoInitAction;
import flash.swf.tags.EnableDebugger;
import flash.swf.tags.ExportAssets;
import flash.swf.tags.FrameLabel;
import flash.swf.tags.GenericTag;
import flash.swf.tags.ImportAssets;
import flash.swf.tags.PlaceObject;
import flash.swf.tags.ProductInfo;
import flash.swf.tags.ScriptLimits;
import flash.swf.tags.SetBackgroundColor;
import flash.swf.tags.ShowFrame;
import flash.swf.tags.FileAttributes;
import flash.swf.types.CXForm;
import flash.swf.types.CurvedEdgeRecord;
import flash.swf.types.FillStyle;
import flash.swf.types.FlashUUID;
import flash.swf.types.GradRecord;
import flash.swf.types.ImportRecord;
import flash.swf.types.LineStyle;
import flash.swf.types.Matrix;
import flash.swf.types.Rect;
import flash.swf.types.ShapeWithStyle;
import flash.swf.types.StraightEdgeRecord;
import flash.swf.types.StyleChangeRecord;
import flash.swf.types.Gradient;
import flash.util.FileUtils;
import flash.util.StringUtils;
import flash.util.Trace;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Stack;

/**
 * This class supports reading in the SWFX format and turning it back
 * into a SWF.  SWFX format can be created by hand or it also can be
 * generated by the swfdump utility.
 *
 * @author Edwin Smith
 * @see SwfxPrinter#main
 */
public class SwfxParser extends DefaultHandler
        implements TagValues
{
    private TagHandler tagHandler;
    private DefineSprite sprite;
    private Locator locator;
    private StringBuilder text;
    private Header header;
    private Stack stack;
    private ArrayList fillstyles;
    private ArrayList linestyles;
    private String docPath;
    private Dictionary dict;
    private String[] aspath;
    private String topLevel;
    private GenericTag jpegTables;
    private int startLineNumber;

    private TagHandler currentHandler()
    {
        return sprite != null ? sprite.tagList : tagHandler;
    }

    public SwfxParser(TagHandler handler, String[] aspath)
    {
        this.tagHandler = handler;
        this.aspath = aspath;
        try
        {
            this.topLevel = FileUtils.readFile(aspath[0] + File.separator + "toplevel.as", null);
        }
        catch (IOException ex)
        {
            this.topLevel = null;
        }

        stack = new Stack();
        dict = new Dictionary();
    }

    public void startElement(String uri, String localName,
                             String qName, Attributes attributes)
            throws SAXException
    {
        try
        {
            Method method = getClass().getMethod(qName, new Class[]{Attributes.class});
            method.invoke(this, new Object[]{attributes});
        }
        catch (NoSuchMethodException e)
        {
            warning(new SAXParseException("no start handler for " + qName, locator));
        }
        catch (IllegalAccessException e)
        {
            fatalError(new SAXParseException(e.getMessage(), locator, e));
        }
        catch (InvocationTargetException e)
        {
            Throwable t = e.getTargetException();
            if (t instanceof SAXException)
            {
                throw (SAXException)t;
            }
            else
            {
                fatalError(new SAXParseException(e.getMessage(), locator, e));
            }
        }
    }

    public void characters(char ch[], int start, int length)
            throws SAXException
    {
        if (text != null)
            text.append(ch, start, length);
    }

    public void curve(Attributes attributes) throws SAXParseException
    {
        CurvedEdgeRecord curvedEdge = new CurvedEdgeRecord();

        curvedEdge.controlDeltaX = parseInt(getAttribute(attributes, "cdx"));
        curvedEdge.controlDeltaY = parseInt(getAttribute(attributes, "cdy"));
        curvedEdge.anchorDeltaX = parseInt(getAttribute(attributes, "dx"));
        curvedEdge.anchorDeltaY = parseInt(getAttribute(attributes, "dy"));

        DefineShape defineShape = (DefineShape)stack.peek();
        defineShape.shapeWithStyle.shapeRecords.add(curvedEdge);
    }

    public void curve()
    {}

    public void DebugID(Attributes attributes) throws SAXParseException
    {
        DebugID debugId = new DebugID(parseUUID(getAttribute(attributes, "uuid")));
        tagHandler.debugID(debugId);
    }

    public void DebugID()
    {
    }

    private FlashUUID parseUUID(String s)
    {
        byte[] b = new byte[s.length() / 2];
        for (int i = 0; i < b.length; i++)
        {
            b[i] = (byte)((Character.digit(s.charAt(2 * i), 16) << 4) |
                    (Character.digit(s.charAt(2 * i + 1), 16) << 0));
        }
        return new FlashUUID(b);
    }

    /**
     * Add an id to the dictionary of characters, tracking what the player
     * would do anyway.  The player will ignore the new definition if another
     * one with the same ID already exists.
     *
     * @param id
     * @param tag
     * @throws SAXParseException
     */
    private void createCharacter(int id, DefineTag tag) throws SAXParseException
    {
        try
        {
            dict.add(id, tag);
        }
        catch (IllegalArgumentException e)
        {
            // player will ignore dups, so print a warning
            error(new SAXParseException(e.getMessage(), locator, e));
        }
    }

    private SwfImageUtils.JPEG loadJPEG(Attributes attributes) throws SAXException
    {
        if (hasAttribute(attributes, "encoding"))
        {
            if (!getAttribute(attributes, "encoding").equals("base64"))
                fatalError(new SAXParseException("unknown encoding "
                        + getAttribute(attributes, "encoding"),
                        locator));
            if (hasAttribute(attributes, "src"))
                fatalError(new SAXParseException("can only specify one of src or encoding attributes", locator));

            text = new StringBuilder();
        }
        else
        {
            text = null;
            if (!hasAttribute(attributes, "src"))
                fatalError(new SAXParseException("must provide either src or encoding attribute", locator));
            try
            {
                File src = new File(getAttribute(attributes, "src"));
                FileInputStream input = new FileInputStream(getAttribute(attributes, "src"));
                byte[] image = new byte[(int)src.length()];
                input.read(image);
                input.close();
                SwfImageUtils.JPEG jpeg = new SwfImageUtils.JPEG(image, true);
                if (!jpeg.validate())
                    fatalError(new SAXParseException("Invalid JPEG data in " + src.getName(), locator));
                return jpeg;
            }
            catch (IOException e)
            {
                throw new SAXParseException(e.getMessage(), locator);
            }
        }
        return null;
    }

    public void DefineBits(Attributes attributes) throws SAXException
    {
        if (jpegTables == null)
            fatalError(new SAXParseException("DefineBits must follow JPEGTables", locator));

        DefineBits db = new DefineBits(stagDefineBits);
        int id = parseInt(getAttribute(attributes, "id"));
        createCharacter(id, db);

        SwfImageUtils.JPEG jpeg = loadJPEG(attributes);

        if (jpeg != null)
        {
            if (!Arrays.equals(jpeg.table, jpegTables.data))
            {
                fatalError(new SAXParseException("JPEGTables data does not match, use DefineBitsJPEG2", locator));
            }
            db.data = jpeg.data;
        }
        stack.push(db);
    }

    public void DefineBits()
    {
        DefineBits db = (DefineBits)stack.pop();
        if (text != null)
        {
            // text is allocated for the base64 encoding

            Base64.Decoder dec = new Base64.Decoder();

            dec.decode(text.toString());

            db.data = dec.flush();
            db.jpegTables = jpegTables;


        }

        currentHandler().defineBits(db);

    }

    public void DefineBitsJPEG2(Attributes attributes) throws SAXException
    {
        DefineBits db = new DefineBits(stagDefineBitsJPEG2);
        int id = parseInt(getAttribute(attributes, "id"));
        createCharacter(id, db);
        if (hasAttribute(attributes, "encoding"))
        {
            if (!getAttribute(attributes, "encoding").equals("base64"))
                fatalError(new SAXParseException("unknown encoding "
                        + getAttribute(attributes, "encoding"),
                        locator));
            if (hasAttribute(attributes, "src"))
                fatalError(new SAXParseException("can only specify one of src or encoding attributes", locator));

            text = new StringBuilder();
        }
        else
        {
            if (!hasAttribute(attributes, "src"))
                fatalError(new SAXParseException("must provide either src or encoding attribute", locator));

            File src = new File(getAttribute(attributes, "src"));

            try
            {
                FileInputStream input = new FileInputStream(getAttribute(attributes, "src"));
                db.data = new byte[(int)src.length()];
                input.read(db.data);
            }
            catch (IOException e)
            {
                fatalError(new SAXParseException("Unable to load DefineBitsJPEG2 src " + src.getName() + ":" + e.getMessage(), locator));
            }
        }
        stack.push(db);
    }

    public void DefineBitsJPEG2()
    {
        DefineBits db = (DefineBits)stack.pop();
        if (text != null)
        {
            // text is allocated for the base64 encoding

            Base64.Decoder dec = new Base64.Decoder();

            dec.decode(text.toString());

            db.data = dec.flush();
            db.jpegTables = null;
        }

        currentHandler().defineBits(db);

    }

    public void DefineShape(Attributes attributes) throws SAXException
    {
        DefineShape tag = new DefineShape(stagDefineShape);
        int id = parseInt(getAttribute(attributes, "id"));
        createCharacter(id, tag);
        tag.bounds = parseRect(getAttribute(attributes, "bounds"));
        tag.shapeWithStyle = new ShapeWithStyle();
        tag.shapeWithStyle.fillstyles = new ArrayList();
        tag.shapeWithStyle.linestyles = new ArrayList();
        tag.shapeWithStyle.shapeRecords = new ArrayList();

        stack.push(tag);
        fillstyles = tag.shapeWithStyle.fillstyles;
        linestyles = tag.shapeWithStyle.linestyles;
    }

    public void DefineShape()
    {
        DefineShape tag = (DefineShape)stack.pop();
        fillstyles = null;
        linestyles = null;
        tagHandler.defineShape(tag);
    }

    public void DefineShape3(Attributes attributes) throws SAXException
    {
        DefineShape tag = new DefineShape(TagValues.stagDefineShape3);
        int id = parseInt(getAttribute(attributes, "id"));
        createCharacter(id, tag);
        tag.bounds = parseRect(getAttribute(attributes, "bounds"));
        tag.shapeWithStyle = new ShapeWithStyle();
        tag.shapeWithStyle.fillstyles = new ArrayList();
        tag.shapeWithStyle.linestyles = new ArrayList();
        tag.shapeWithStyle.shapeRecords = new ArrayList();

        stack.push(tag);
        fillstyles = tag.shapeWithStyle.fillstyles;
        linestyles = tag.shapeWithStyle.linestyles;
    }

    public void DefineShape3()
    {
        DefineShape tag = (DefineShape)stack.pop();
        fillstyles = null;
        linestyles = null;
        tagHandler.defineShape3(tag);
    }

    public void DefineSprite(Attributes attributes) throws SAXParseException
    {
        DefineSprite sprite = new DefineSprite();
        int id = parseInt(getAttribute(attributes, "id"));
        createCharacter(id, sprite);
        stack.push(sprite);
        this.sprite = sprite;
    }

    public void DefineSprite()
    {
        DefineSprite sprite = (DefineSprite)stack.pop();
        this.sprite = null;
        tagHandler.defineSprite(sprite);
    }

    public void DoAction(Attributes attributes)
    {
        text = new StringBuilder();
        startLineNumber = locator.getLineNumber();
    }

    public void DoAction() throws SAXException
    {
        //try
        //{
            //String code = text.toString();
            text = null;

            /*
            AsActionsContainerInfo info = new AsActionsContainerInfo();
            ActionScriptCompiler compiler = packageManager.createCompiler(info, ActionType.kFrameActions,
                    CompileFlags.kCompileString,
                    startLineNumber);
            compiler.setFileName(docPath);
            compiler.compile(code, true);
            if (compiler.errorsExist())
            {
                throw new SAXParseException("compile failed", locator);
            }
            byte[] bytecode = compiler.getAsBytes();
            */
            DoAction doAction = new DoAction();

            //SwfDecoder r = new SwfDecoder(bytecode, header.version);
            //doAction.actionList = new ActionDecoder(r).decode(bytecode.length);

            currentHandler().doAction(doAction);
        //}
        //catch (IOException e)
        //{
        //    fatalError(new SAXParseException(e.getMessage(), locator, e));
        //}
    }

    public void ProductInfo(Attributes attributes) throws SAXException
    {
        int product = parseInt(getAttribute(attributes, "product"));
        int edition = parseInt(getAttribute(attributes, "edition"));
        byte majorVersion = Byte.parseByte(getAttribute(attributes, "majorVersion"));
        byte minorVersion = Byte.parseByte(getAttribute(attributes, "majorVersion"));
        long build = Long.parseLong(getAttribute(attributes, "build"));
        long compileDate = Long.parseLong(getAttribute(attributes, "compileDate"));

        stack.push(new ProductInfo(product, edition, majorVersion, minorVersion, build, compileDate));
    }

    public void FileAttributes()
    {
        tagHandler.fileAttributes((FileAttributes)stack.pop());
    }

    public void FileAttributes(Attributes attributes) throws SAXException
    {
        FileAttributes tag = new FileAttributes();
        tag.useDirectBlit = parseBoolean(getAttribute(attributes, "useDirectBlit"));
        tag.useGPU = parseBoolean(getAttribute(attributes, "useGPU"));
        tag.hasMetadata = parseBoolean(getAttribute(attributes, "hasMetadata"));
        tag.actionScript3 = parseBoolean(getAttribute(attributes, "actionScript3"));
        tag.suppressCrossDomainCaching = parseBoolean(getAttribute(attributes, "suppressCrossDomainCaching"));
        tag.swfRelativeUrls = parseBoolean(getAttribute(attributes, "swfRelativeUrls"));
        tag.useNetwork = parseBoolean(getAttribute(attributes, "useNetwork"));
        stack.push(tag);
    }

    public void ProductInfo()
    {
        tagHandler.productInfo((ProductInfo)stack.pop());
    }

    private DefineTag findCharacter(int idref) throws SAXParseException
    {
        try
        {
            return dict.getTag(idref);
        }
        catch (IllegalArgumentException e)
        {
            //return null;
            throw new SAXParseException(e.getMessage(), locator, e);
        }
    }

    public void Package(Attributes attributes) throws SAXParseException
    {
        text = new StringBuilder();
        DefineSprite pkg = new DefineSprite();
        DoInitAction initAction = new DoInitAction(pkg);
        // get id for this package
        int id = parseInt(getAttribute(attributes, "id"));
        createCharacter(id, pkg);
        currentHandler().defineSprite(pkg);
        startLineNumber = locator.getLineNumber();
        stack.push(initAction);
    }

    public void Package() throws SAXException
    {
        //try
        //{
        //    String code = text.toString();
            text = null;
            DoInitAction initAction = (DoInitAction)stack.pop();

            /*
            AsActionsContainerInfo info = new AsActionsContainerInfo();
            info.setModuleName(docPath);
            ActionScriptCompiler compiler = packageManager.createCompiler(info, ActionType.kPackageActions,
                    CompileFlags.kCompileString,
                    startLineNumber);
            // don't set the filename here because it makes AS2 compilain about the filename
            //compiler.setFileName(docPath);
            compiler.compile(code, true);
            if (compiler.errorsExist())
            {
                throw new SAXParseException("compile failed", locator);
            }
            byte[] bytecode = compiler.getAsBytes();
            */
            //ActionDecoder actionDecoder = new ActionDecoder(new SwfDecoder(bytecode, header.version));
            //initAction.actionList = actionDecoder.decode(bytecode.length);

            currentHandler().doInitAction(initAction);
        //}
        //catch (IOException e)
        //{
        //    fatalError(new SAXParseException(e.getMessage(), locator, e));
        //}
    }

    public void DoInitAction(Attributes attributes) throws SAXParseException
    {
        text = new StringBuilder();
        DoInitAction initAction = new DoInitAction();
        // get id of previous DefineSprite
        int idref = parseInt(getAttribute(attributes, "idref"));
        initAction.sprite = (DefineSprite)findCharacter(idref);
        startLineNumber = locator.getLineNumber();
        stack.push(initAction);
    }

    public void DoInitAction() throws SAXException
    {
        //try
        //{
            //String code = text.toString();
            text = null;
            DoInitAction initAction = (DoInitAction)stack.pop();

            /*
            AsActionsContainerInfo info = new AsActionsContainerInfo();
            ActionScriptCompiler compiler = packageManager.createCompiler(info, ActionType.kUndefinedActions,
                    CompileFlags.kCompileString,
                    startLineNumber);
            compiler.setFileName(docPath);
            compiler.compile(code, true);
            if (compiler.errorsExist())
            {
                throw new SAXParseException("compile failed", locator);
            }
            byte[] bytecode = compiler.getAsBytes();
            ActionDecoder actionDecoder = new ActionDecoder(new SwfDecoder(bytecode, header.version));
            initAction.actionList = actionDecoder.decode(bytecode.length);
            */

            currentHandler().doInitAction(initAction);
        //}
        //catch (IOException e)
        //{
        //    fatalError(new SAXParseException(e.getMessage(), locator, e));
        //}
    }

    public void EnableDebugger2(Attributes attributes) throws SAXParseException
    {
        EnableDebugger enableDebugger2 = new EnableDebugger(stagEnableDebugger2);
        enableDebugger2.password = getAttribute(attributes, "password");
        tagHandler.enableDebugger2(enableDebugger2);
    }

    public void EnableDebugger2()
    {}

    public void ExportAssets(Attributes attributes)
    {
        ExportAssets tag = new ExportAssets();
        stack.push(tag);
    }

    public void ExportAssets()
    {
        ExportAssets tag = (ExportAssets)stack.pop();
        tagHandler.exportAssets(tag);
    }

    public void Export(Attributes attributes) throws SAXParseException
    {
        ExportAssets tag = (ExportAssets)stack.peek();
        int idref = parseInt(getAttribute(attributes, "idref"));
        String name = getAttribute(attributes, "name");
        DefineTag ref = findCharacter(idref);
        ref.name = name;
        tag.exports.add(ref);
    }

    public void Export()
    {
    }

    public void fillstyle(Attributes attributes) throws SAXParseException
    {
        DefineShape defineShape = (DefineShape)stack.peek();
        boolean hasAlpha = (defineShape.code == stagDefineShape3);
        FillStyle fillstyle = new FillStyle();
        if (hasAttribute(attributes, "color"))
        {
            fillstyle.setType(FillStyle.FILL_SOLID);
            fillstyle.color = hasAlpha ? parseRGBA(getAttribute(attributes, "color")) :
                    parseRGB(getAttribute(attributes, "color"));
        }
        if (hasAttribute(attributes, "gradient"))
        {
            // todo support radial gradients
            fillstyle.setType(FillStyle.FILL_LINEAR_GRADIENT);
            fillstyle.gradient = parseGradient(getAttribute(attributes, "gradient"), hasAlpha);
            fillstyle.matrix = parseMatrix(getAttribute(attributes, "matrix"));
        }
        if (hasAttribute(attributes, "idref"))
        {
            // todo support clipped bitmaps
            fillstyle.setType(FillStyle.FILL_BITS); // tiled
            int idref = parseInt(getAttribute(attributes, "idref"));
            // todo check to make sure bitmapId points to a bitmap
            fillstyle.bitmap = findCharacter(idref);
            fillstyle.matrix = parseMatrix(getAttribute(attributes, "matrix"));
        }

        defineShape.shapeWithStyle.fillstyles.add(fillstyle);
    }

    public void fillstyle()
    {}

    public void FrameLabel(Attributes attributes) throws SAXParseException
    {
        FrameLabel frameLabel = new FrameLabel();
        frameLabel.label = getAttribute(attributes, "label");
        frameLabel.anchor = parseBoolean(getAttribute(attributes, "anchor"));
        tagHandler.frameLabel(frameLabel);
    }

    public void FrameLabel()
    {}

    public void Import(Attributes attributes) throws SAXParseException
    {
        ImportRecord record = new ImportRecord();
        int id = parseInt(getAttribute(attributes, "id"));
        record.name = getAttribute(attributes, "name");

        ImportAssets importAssets = (ImportAssets)stack.peek();
        importAssets.importRecords.add(record);

        // todo find the actual tag imported
        createCharacter(id, record);
    }

    public void Import()
    {}

    public void ImportAssets(Attributes attributes) throws SAXParseException
    {
        ImportAssets importAssets = new ImportAssets(stagImportAssets);
        importAssets.url = getAttribute(attributes, "url");
        importAssets.importRecords = new ArrayList();
        stack.push(importAssets);
    }

    public void ImportAssets()
    {
        ImportAssets importAssets = (ImportAssets)stack.pop();
        tagHandler.importAssets(importAssets);
    }

    public void line(Attributes attributes) throws SAXParseException
    {
        StraightEdgeRecord straightEdge = new StraightEdgeRecord();
        if (hasAttribute(attributes, "dx"))
        {
            straightEdge.deltaX = parseInt(getAttribute(attributes, "dx"));
        }
        if (hasAttribute(attributes, "dy"))
        {
            straightEdge.deltaY = parseInt(getAttribute(attributes, "dy"));
        }

        DefineShape defineShape = (DefineShape)stack.peek();
        defineShape.shapeWithStyle.shapeRecords.add(straightEdge);
    }

    public void line()
    {}

    public void linestyle(Attributes attributes) throws SAXParseException
    {
        DefineShape defineShape = (DefineShape)stack.peek();
        LineStyle linestyle = new LineStyle();
        if (defineShape.code == stagDefineShape3)
        {
            linestyle.color = parseRGBA(getAttribute(attributes, "color"));
        }
        else
        {
            linestyle.color = parseRGB(getAttribute(attributes, "color"));
        }
        linestyle.width = parseInt(getAttribute(attributes, "width"));
        linestyles.add(linestyle);
    }

    public void linestyle()
    {}

    public void swf(Attributes attributes) throws SAXException
    {
        Header h = new Header();
        h.version = parseInt(getAttribute(attributes, "version"));
        h.compressed = parseBoolean(getAttribute(attributes, "compressed"));
        h.rate = parseInt(getAttribute(attributes, "framerate"));
        h.size = parseRect(getAttribute(attributes, "size"));
        this.header = h;
        tagHandler.header(h);

        /*
        this.packageManager = new CompilerPackageManager(h.version, topLevel, 0);

        // register an asclassloader for the given aspath
        ASClassLoader asLoader = new ASClassLoader(aspath, false, null);
        asLoader.pm = packageManager;
        asLoader.debug = false;
        packageManager.addLoader(asLoader);
        packageManager.findType("String");

        MessageHandler.setThreadLocalMessageHandler(outputHandler);
        */
    }

    public void swf()
    {
    }

    public void JPEGTables(Attributes attributes) throws SAXParseException
    {
        text = new StringBuilder();
        if (hasAttribute(attributes, "encoding"))
        {
            if (!getAttribute(attributes, "encoding").equals("base64"))
                fatalError(new SAXParseException("unknown encoding "
                        + getAttribute(attributes, "encoding"),
                        locator));
        }
    }

    public void JPEGTables()
    {
        if (text != null)
        {
            String encoded = text.toString();
            text = null;

            Base64.Decoder dec = new Base64.Decoder();

            dec.decode(encoded);

            jpegTables = new GenericTag(stagJPEGTables);
            jpegTables.data = dec.flush();
            currentHandler().jpegTables(jpegTables);

        }
    }

    public void ShowFrame(Attributes attributes)
    {
        currentHandler().showFrame(new ShowFrame());

        if (sprite != null)
        {
            sprite.framecount++;
        }
        else
        {
            header.framecount++;
        }
    }

    public void ShowFrame()
    {
    }

    public void styleChange(Attributes attributes) throws SAXParseException
    {
        StyleChangeRecord styleChange = new StyleChangeRecord();
        if (hasAttribute(attributes, "dx") || hasAttribute(attributes, "dy"))
        {
            styleChange.stateMoveTo = true;
            styleChange.moveDeltaX = parseInt(getAttribute(attributes, "dx"));
            styleChange.moveDeltaY = parseInt(getAttribute(attributes, "dy"));
        }
        if (hasAttribute(attributes, "fillStyle0"))
        {
            styleChange.stateFillStyle0 = true;
            styleChange.fillstyle0 = parseInt(getAttribute(attributes, "fillStyle0"));
        }
        if (hasAttribute(attributes, "fillStyle1"))
        {
            styleChange.stateFillStyle1 = true;
            styleChange.fillstyle1 = parseInt(getAttribute(attributes, "fillStyle1"));
        }
        if (hasAttribute(attributes, "lineStyle"))
        {
            styleChange.stateLineStyle = true;
            styleChange.linestyle = parseInt(getAttribute(attributes, "lineStyle"));
        }
        styleChange.fillstyles = new ArrayList();
        styleChange.linestyles = new ArrayList();
        fillstyles = styleChange.fillstyles;
        linestyles = styleChange.linestyles;
        stack.push(styleChange);
    }

    public void styleChange()
    {
        StyleChangeRecord styleChange = (StyleChangeRecord)stack.pop();
        if (fillstyles.size() != 0)
        {
            styleChange.stateNewStyles = true;
        }

        DefineShape defineShape = (DefineShape)stack.peek();
        defineShape.shapeWithStyle.shapeRecords.add(styleChange);
        fillstyles = defineShape.shapeWithStyle.fillstyles;
        linestyles = defineShape.shapeWithStyle.linestyles;
    }

    public void PlaceObject2(Attributes attributes) throws SAXParseException
    {
        PlaceObject tag = new PlaceObject(stagPlaceObject2);
        tag.depth = parseInt(getAttribute(attributes, "depth"));
        if (hasAttribute(attributes, "className"))
        {
            tag.setClassName(getAttribute(attributes, "className"));
        }
        if (hasAttribute(attributes, "hasImage"))
        {
            tag.setHasImage(getAttribute(attributes, "hasImage").equals("true"));
        }
        if (hasAttribute(attributes, "idref"))
        {
            int idref = parseInt(getAttribute(attributes, "idref"));
            tag.setRef(findCharacter(idref));
        }
        if (hasAttribute(attributes, "name"))
        {
            tag.setName(getAttribute(attributes, "name"));
        }
        if (hasAttribute(attributes, "clipDepth"))
        {
            tag.setClipDepth(parseInt(getAttribute(attributes, "clipDepth")));
        }
        if (hasAttribute(attributes, "ratio"))
        {
            tag.setRatio(parseInt(getAttribute(attributes, "ratio")));
        }
        if (hasAttribute(attributes, "cxform"))
        {
            tag.setCxform(parseCXForm(getAttribute(attributes, "cxform")));
        }
        if (hasAttribute(attributes, "matrix"))
        {
            tag.setMatrix(parseMatrix(getAttribute(attributes, "matrix")));
        }

        stack.push(tag);
        text = new StringBuilder();
    }

    public void PlaceObject2() throws SAXException
    {
        PlaceObject tag = (PlaceObject)stack.pop();
        //try
        //{
            //String code = text.toString();
            text = null;

            /*
            if (code.length() > 0)
            {
                AsActionsContainerInfo info = new AsActionsContainerInfo();
                ActionScriptCompiler compiler = packageManager.createCompiler(info, ActionType.kSpriteActions,
                        CompileFlags.kCompileString,
                        locator.getLineNumber());
                compiler.setFileName(docPath);
                compiler.compile(code, true);
                if (compiler.errorsExist())
                {
                    throw new SAXParseException("compile failed", locator);
                }
                byte[] bytecode = compiler.getAsBytes();

                ActionDecoder decoder = new ActionDecoder(new SwfDecoder(bytecode, header.version));
                tag.setClipActions(decoder.decodeClipActions(bytecode.length));
            }
            */

            currentHandler().placeObject2(tag);
        //}
        //catch (IOException e)
        //{
        //    fatalError(new SAXParseException(e.getMessage(), locator, e));
        //}
    }

    public void SetBackgroundColor(Attributes attributes) throws SAXParseException
    {
        SetBackgroundColor tag = new SetBackgroundColor(parseRGB(getAttribute(attributes, "color")));
        currentHandler().setBackgroundColor(tag);
    }

    public void SetBackgroundColor()
    {
    }

    public void ScriptLimits(Attributes attributes) throws SAXParseException
    {
        ScriptLimits tag = new ScriptLimits(parseInt(getAttribute(attributes, "maxRecursionLimit")),
                parseInt(getAttribute(attributes, "scriptTimeLimit")));
        currentHandler().scriptLimits(tag);
    }

    public void ScriptLimits()
    {
    }

    private Matrix parseMatrix(String s)
    {
        Matrix matrix = new Matrix();
        for (int i = 0; i < s.length(); i++)
        {
            char c = s.charAt(i);
            switch (c)
            {
                case 'r':
                    i++;
                    String[] parts = StringUtils.split(s.substring(i), "[, ]", 3);
                    matrix.setRotate(Double.parseDouble(parts[0]), Double.parseDouble(parts[1]));
                    break;
                case 's':
                    i++;
                    parts = StringUtils.split(s.substring(i), "[, ]", 3);
                    matrix.setScale(Double.parseDouble(parts[0]), Double.parseDouble(parts[1]));
                    break;
                case 't':
                    i++;
                    parts = StringUtils.split(s.substring(i), "[, ]", 3);
                    matrix.translateX = Integer.parseInt(parts[0]);
                    matrix.translateY = Integer.parseInt(parts[1]);
                    break;
            }
        }
        return matrix;
    }

    private Gradient parseGradient(String s, boolean hasAlpha)
    {
        Gradient gradient = new Gradient(); // todo - support focal

        // todo add error checking
        //    count must be 1..8
        //    number of parts must be even
        //    ratio must be 0..255
        String[] parts = StringUtils.split(s, " ");
        int count = parts.length / 2;
        gradient.records = new GradRecord[count];
        for (int i = 0; i < count; i++)
        {
            GradRecord record = gradient.records[i] = new GradRecord();
            record.ratio = Integer.parseInt(parts[2 * i]);
            record.color = hasAlpha ? parseRGBA(parts[2 * i + 1]) : parseRGB(parts[2 * i + 1]);
        }
        return gradient;
    }

    private CXForm parseCXForm(String s)
    {
        // todo add error checking
        //    must be six parts
        //    each term must be -32768..32767
        String[] parts = StringUtils.split(s, "([rgb]\\+?| )");
        CXForm cxform = new CXForm();
        cxform.redAddTerm = Integer.parseInt(parts[0]);
        cxform.redMultTerm = Integer.parseInt(parts[1]);
        cxform.greenAddTerm = Integer.parseInt(parts[2]);
        cxform.greenMultTerm = Integer.parseInt(parts[3]);
        cxform.blueAddTerm = Integer.parseInt(parts[4]);
        cxform.blueMultTerm = Integer.parseInt(parts[5]);
        return cxform;
    }

    private boolean parseBoolean(String attribute)
    {
        return Boolean.valueOf(attribute).booleanValue();
    }

    /**
     * @param s
     * @return 0x00RRGGBB
     */
    private int parseRGB(String s)
    {
        int rgb = parseColor(s);
        int color = ((rgb >> 16) & 255) << 16; // red
        color |= ((rgb >> 8) & 255) << 8; // green
        color |= ((rgb >> 0) & 255); // blue
        return color;
    }

    /**
     * @param s
     * @return 0xAARRGGBB
     */
    private int parseRGBA(String s)
    {
        int rgb = parseColor(s);
        int color = ((rgb >> 24) & 255) << 16; // red
        color |= ((rgb >> 16) & 255) << 8; // green
        color |= ((rgb >> 8) & 255); // blue
        color |= ((rgb >> 0) & 255) << 24; // alpha
        return color;
    }

    public static int parseColor(String string)
    {
        if (string.length() > 0)
        {
            if (string.charAt(0) == '#')
            {
                return (int)Long.parseLong(string.substring(1), 16);
            }
            else if (string.startsWith("0x") || string.startsWith("0X"))
            {
                return Integer.parseInt(string.substring(2), 16);
            }
            else
            {
                return Integer.parseInt(string);
            }
        }
        else
        {
            return 0;
        }
    }

    private boolean hasAttribute(Attributes attributes, String qName)
    {
        return attributes.getValue(qName) != null;
    }

    private String getAttribute(Attributes attributes, String qName) throws SAXParseException
    {
        String value = attributes.getValue(qName);
        if (value == null)
        {
            error(new SAXParseException("attribute not found: " + qName, locator));
        }
        return value;
    }

    private Rect parseRect(String s)
    {
        String[] parts = StringUtils.split(s, "x");
        return new Rect(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]));
    }

    private int parseInt(String s)
    {
        return Integer.parseInt(s);
    }

    public void endElement(String uri, String localName, String qName)
            throws SAXException
    {
        try
        {
            Method method = getClass().getMethod(qName, new Class[]{});
            method.invoke(this, new Object[]{});
        }
        catch (NoSuchMethodException e)
        {
            warning(new SAXParseException("no end handler for " + qName, locator));
        }
        catch (IllegalAccessException e)
        {
            fatalError(new SAXParseException(e.getMessage(), locator, e));
        }
        catch (InvocationTargetException e)
        {
            Throwable t = e.getTargetException();
            if (t instanceof SAXException)
            {
                throw (SAXException)t;
            }
            else if (t instanceof Error)
            {
                throw (Error)t;
            }
            else
            {
                fatalError(new SAXParseException(t.getMessage(), locator));
            }
        }
    }

    public void endDocument()
            throws SAXException
    {
        tagHandler.finish();
    }

    public void warning(SAXParseException e)
            throws SAXParseException
    {
        //outputHandler.warning(0, e.getLineNumber(), docPath, e.getMessage());
    }

    public void error(SAXParseException e)
            throws SAXParseException
    {
        //outputHandler.error(0, e.getLineNumber(), docPath, e.getMessage());
    }

    public void fatalError(SAXParseException e)
            throws SAXParseException
    {
        //outputHandler.error(0, e.getLineNumber(), docPath, e.getMessage());
        throw e;
    }

    public void setDocumentLocator(Locator locator)
    {
        this.locator = locator;
    }


    public boolean parse(String path) throws IOException//, OutputHandler handler) throws IOException
    {
        // parser property names
        final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
        final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";

        final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";

        this.docPath = path;
        //this.outputHandler = handler;

        InputStream in = new BufferedInputStream(new FileInputStream(path));
        SAXParser parser;
        try
        {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            factory.setValidating(true);
            factory.setNamespaceAware(true);
            try
            {
                parser = factory.newSAXParser();
                parser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
                parser.setProperty(JAXP_SCHEMA_SOURCE,
                        new InputSource(getClass().getResource("swfx.xsd").toExternalForm()));
            }
            catch (Exception e)
            {
                if (e instanceof SAXNotRecognizedException)
                {
                    // schema validation not supported... ignore
                    factory.setValidating(false);
                    factory.setNamespaceAware(true);
                    parser = factory.newSAXParser();
                }
                else if (e instanceof IOException)
                {
                    throw (IOException)e;
                }
                else if (e instanceof SAXException)
                {
                    throw (SAXException)e;
                }
                else
                {
                    e.printStackTrace();
                    parser = null;
                }
            }
            parser.parse(in, this);
            return true;
        }
        catch (SAXException e)
        {
            // errors will have been reported already
            //e.printStackTrace();
            return false;
        }
        catch (Exception e)
        {
            if (e instanceof ParserConfigurationException)
            {
                if (Trace.error)
                    e.printStackTrace();

                return false;
            }
            else if (e instanceof IOException)
            {
                throw (IOException)e;
            }
            else
            {
                e.printStackTrace();
                return true;
            }
        }
        finally
        {
            in.close();
        }
    }

    public static void main(String[] args) throws IOException
    {
        String aspath = null;
        for (int i = 0; i < args.length; i++)
        {
            if (args[i].equals("-aspath"))
            {
                aspath = args[++i];
                continue;
            }
            TagEncoder encoder = new TagEncoder();
            //ConsoleOutputHandler tagHandler = new ConsoleOutputHandler(null, null);
            SwfxParser swfxParser = new SwfxParser(encoder, StringUtils.splitPath(aspath));
            boolean success = swfxParser.parse(args[i]);//, tagHandler);
            if (success)
            {
                String swfFileName = args[i].substring(0, args[i].lastIndexOf('.')) + ".swf";
                OutputStream out = new BufferedOutputStream(new FileOutputStream(swfFileName));
                try
                {
                    encoder.writeTo(out);
                }
                finally
                {
                    out.close();
                }
            }
            else
            {
                System.exit(1);
            }
        }
    }
}
