__author__ = 'ardevelop'

import struct
import zlib
import cStringIO

read_ui8 = lambda c: struct.unpack("<B", c)[0]
read_ui16 = lambda c: struct.unpack("<H", c)[0]
read_ui32 = lambda c: struct.unpack("<I", c)[0]


def from_stream(stream):
    metadata = {}

    signature = "".join(struct.unpack("<3c", stream.read(3)))
    if signature not in ("FWS", "CWS"):
        raise ValueError("Invalid SWF signature: %s." % signature)

    metadata["compressed"] = signature.startswith("C")
    metadata["version"] = read_ui8(stream.read(1))
    metadata["size"] = read_ui32(stream.read(4))

    buf = stream.read(metadata["size"])
    if metadata["compressed"]:
        buf = zlib.decompress(buf)

    nbits = read_ui8(buf[0]) >> 3

    current_byte, buf = read_ui8(buf[0]), buf[1:]
    bit_cursor = 5

    for item in "xmin", "xmax", "ymin", "ymax":
        value = 0
        for value_bit in xrange(nbits - 1, -1, -1):
            if (current_byte << bit_cursor) & 0x80:
                value |= 1 << value_bit
            bit_cursor += 1

            if bit_cursor > 7:
                current_byte, buf = read_ui8(buf[0]), buf[1:]
                bit_cursor = 0

        metadata[item] = value / 20

    metadata["width"] = metadata["xmax"] - metadata["xmin"]
    metadata["height"] = metadata["ymax"] - metadata["ymin"]

    metadata["fps"] = read_ui16(buf[0:2]) >> 8
    metadata["frames"] = read_ui16(buf[2:4])

    return metadata


def metadata(swf=None, filename=None):
    if filename:
        with open(filename, "r") as stream:
            return from_stream(stream)
    elif swf:
        if hasattr(swf, "read") and hasattr(swf, "seek"):
            swf.seek(0)
            return from_stream(swf)
        elif isinstance(swf, str):
            stream = cStringIO.StringIO(swf)
            try:
                return from_stream(stream)
            finally:
                stream.close()

    raise ValueError("Invalid input: %s." % type(swf))

if "__main__" == __name__:
    import sys
    if len(sys.argv) > 1:
        filename = sys.argv[1]
    else:
        sys.stdout.write("Path to swf: ")
        filename = sys.stdin.readline()[:-1]

    print metadata(filename=filename)