/*
 *
 *  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.tags.EnableTelemetry;
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.
 * @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"));
        tag.brokerProductManager = parseBoolean(getAttribute(attributes, "brokerProductManager"));
        tag.brokerLocalConnection = parseBoolean(getAttribute(attributes, "brokerLocalConnection"));
        stack.push(tag);
    }
    
    public void EnableTelemetry()
    {
        tagHandler.enableTelemetry((EnableTelemetry)stack.pop());
    }

    public void EnableTelemetry(Attributes attributes) throws SAXException
    {
    	EnableTelemetry tag = new EnableTelemetry();
        tag.enabled = parseBoolean(getAttribute(attributes, "advancedTelemetry"));
        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);
            }
        }
    }
}
