added some more generic tag functions.
[swftools.git] / lib / python / tag.c
index a08e661..5d55fb3 100644 (file)
 #include "tagmap.h"
 
 //----------------------------------------------------------------------------
-typedef struct {
+
+typedef struct _TagObject {
     PyObject_HEAD
-    PyObject* tagmap;
-    TAG*tag;
-    /* ST_DEFINEFONT*/
-    SWFFONT* font;
-    /* ST_PLACEOBJECT, ST_PLACEOBJECT2*/
-    SWFPLACEOBJECT* placeobject;
-    PyObject* character;
+    tag_internals_t internals;
 } TagObject;
 
 //----------------------------------------------------------------------------
+static PyMethodDef generic_methods[] = 
+{
+  {NULL, NULL, 0, NULL}
+};
+static tag_internals_t generic_tag =
+{
+    parse: 0,
+    dealloc: 0,
+    fillTAG: 0,
+    tagfunctions: generic_methods,
+    datasize: 0,
+};
+//----------------------------------------------------------------------------
+
+static struct tag_parser {
+    int id;
+    tag_internals_t*spec;
+    struct tag_parser* next;
+} tag_parsers[1024];
+static char parsers_initialized = 0;
+
+void register_tag(int id, tag_internals_t*spec)
+{
+    assert(id>=0 && id<1024);
+    if(!parsers_initialized) {
+       memset(tag_parsers, 0, sizeof(tag_parsers));
+       parsers_initialized = 1;
+    }
+    tag_parsers[id].id = id;
+    tag_parsers[id].spec = spec;
+};
+
+static tag_internals_t* get_parser(int id)
+{
+    if(parsers_initialized<2) {
+       int t;
+       struct tag_parser*last = &tag_parsers[0];
+       for(t=0;t<1024;t++) {
+           if(tag_parsers[t].spec) {
+               last->next = &tag_parsers[t];
+               last = &tag_parsers[t];
+           }
+       }
+       parsers_initialized = 2;
+    }
+    assert(id>=0 && id<1024);
+    return tag_parsers[id].spec;
+}
+
+//----------------------------------------------------------------------------
 static void tag_dealloc(PyObject * self)
 {
     TagObject*tag = (TagObject*)self;
-    if(tag->tag)
-       mylog("-%08x(%d) tag_dealoc [%s]\n", (int)self, self->ob_refcnt, swf_TagGetName(tag->tag));
+    if(tag->internals.tag)
+       mylog("-%08x(%d) tag_dealoc [%s]\n", (int)self, self->ob_refcnt, swf_TagGetName(tag->internals.tag));
     else
        mylog("-%08x(%d) tag_dealoc [?]\n", (int)self, self->ob_refcnt);
-    if(tag->placeobject) {
-       swf_PlaceObjectFree(tag->placeobject);
-       tag->placeobject = 0;
-    }
-    if(tag->font) {
-       swf_FontFree(tag->font);
-       tag->font = 0;
+    if(tag->internals.dealloc) {
+       if(!tag->internals.data)
+           mylog("-%08x(%d) tag_dealoc: Warning: calling dealloc without any data(?)\n", (int)self, self->ob_refcnt);
+       tag->internals.dealloc(&tag->internals);
     }
-    if(tag->character) {
-       Py_DECREF(tag->character);
-       tag->character = 0;
+    if(tag->internals.data) {
+       free(tag->internals.data);
+       tag->internals.data = 0;
     }
-    if(tag->tag) {
-       swf_DeleteTag(tag->tag);
-       tag->tag = 0;
+    if(tag->internals.tag) {
+       swf_DeleteTag(tag->internals.tag);
+       tag->internals.tag = 0;
     }
-    Py_DECREF(tag->tagmap);
-    tag->tagmap = 0;
+    Py_DECREF(tag->internals.tagmap);
+    tag->internals.tagmap = 0;
     PyObject_Del(self);
 }
 //----------------------------------------------------------------------------
-static PyObject* tag_setU8(PyObject * self, PyObject*other)
+static int fillTAG(PyObject*self) 
 {
-    return NULL;
+    TagObject*tag = (TagObject*)self;
+    if(tag->internals.tag)
+       return 1;
+    if(!tag->internals.fillTAG) {
+       PyErr_SetString(PyExc_Exception, setError("No way to fill TAG with data"));
+       return 0;
+    }
+    if(!tag->internals.fillTAG(&tag->internals)) {
+       return 0; // pass through exception
+    }
+    if(!tag->internals.tag) {
+       PyErr_SetString(PyExc_Exception, setError("Couldn't fill tag"));
+       return 0;
+    }
+    return 1;
 }
 //----------------------------------------------------------------------------
-static PyObject* tag_setbackgroundcolor_getrgb(PyObject * self, PyObject*other)
+static PyObject* tag_isShape(PyObject * _self, PyObject*args)
 {
-    TagObject*tag = (TagObject*)self;
-    int r,g,b;
-    r = tag->tag->data[0];
-    g = tag->tag->data[1];
-    b = tag->tag->data[2];
-    return Py_BuildValue("(iii)", r,g,b);
+    TagObject*self = (TagObject*)_self;
+    if(!PyArg_ParseTuple(args, "")) return NULL;
+    if(!fillTAG((PyObject*)self))   return NULL;
+    return PyInt_FromLong(swf_isShapeTag(self->internals.tag));
 }
-//----------------------------------------------------------------------------
-
-static struct tagfunctions {
-    int id;
-    PyMethodDef f[8];
-} tagfunctions[] =
+static PyObject* tag_isImage(PyObject * _self, PyObject*args)
 {
- { 
-   ST_SETBACKGROUNDCOLOR, 
-   {{"getRGB", tag_setbackgroundcolor_getrgb, METH_VARARGS, "get's the color set by this tag"},
-    {NULL, NULL, 0, NULL}
-   }
- }
-};
+    TagObject*self = (TagObject*)_self;
+    if(!PyArg_ParseTuple(args, "")) return NULL;
+    if(!fillTAG((PyObject*)self))   return NULL;
+    return PyInt_FromLong(swf_isImageTag(self->internals.tag));
+}
+static PyObject* tag_isDefiningTag(PyObject * _self, PyObject*args)
+{
+    TagObject*self = (TagObject*)_self;
+    if(!PyArg_ParseTuple(args, "")) return NULL;
+    if(!fillTAG((PyObject*)self))   return NULL;
+    return PyInt_FromLong(swf_isDefiningTag(self->internals.tag));
+}
+static PyObject* tag_getBBox(PyObject * _self, PyObject*args)
+{
+    TagObject*self = (TagObject*)_self;
+    if(!PyArg_ParseTuple(args, "")) return NULL;
+    if(!fillTAG((PyObject*)self))   return NULL;
+    return f_BBox2(swf_GetDefineBBox(self->internals.tag));
+}
+//----------------------------------------------------------------------------
 static PyMethodDef common_tagfunctions[] =
-{{"setU8", tag_setU8, METH_VARARGS, "sets a byte to the tag data"},
+{{"isShape", tag_isShape, METH_VARARGS, "tests whether the tag is a shape tag"},
+ {"isImage", tag_isImage, METH_VARARGS, "tests whether the tag is an image"},
+ {"isDefiningTag", tag_isDefiningTag, METH_VARARGS, "tests whether the tag is a defining tag"},
+ {"getBBox", tag_getBBox, METH_VARARGS, "get's the tags bounding box"},
  {NULL, NULL, 0, NULL}
 };
 
@@ -86,271 +151,134 @@ static PyObject* tag_getattr(PyObject * self, char* a)
 {
     TagObject*tag = (TagObject*)self;
     PyObject* ret = NULL;
-    int id =  tag->tag->id;
     int t;
 
     /* -- fields -- */
-    if(!strcmp(a, "id")) {
-       return Py_BuildValue("i", id);
+    if(!strcmp(a, "tagid")) {
+       if(!fillTAG(self))
+           return 0;
+       return Py_BuildValue("i", tag->internals.tag->id);
     }
     if(!strcmp(a, "name")) {
-       char* name = swf_TagGetName(tag->tag);
+       if(!fillTAG(self))
+           return 0;
+       char* name = swf_TagGetName(tag->internals.tag);
        return Py_BuildValue("s", name);
     }
-/*    if(!strcmp(a, "swf")) {
-       if(tag->swf == 0)
-           return Py_BuildValue("s", 0);
-       else {
-           Py_INCREF(tag->swf);
-           return tag->swf;
-       }
-    }*/
-    /* ------------ */
-   
+    if(tag->internals.getattr) {
+       PyObject* ret = tag->internals.getattr(&tag->internals, a);
+       if(ret) return ret;
+    }
+    
     /* search for a tag specific function */
-    for(t=0;t<sizeof(tagfunctions)/sizeof(tagfunctions[0]);t++)
-    {
-       if(id==tagfunctions[t].id) {
-           mylog(" %08x(%d) tag_getattr: id %d found\n", (int)self, self->ob_refcnt, id);
-           ret = Py_FindMethod(tagfunctions[t].f, self, a);
-           if(!ret) return ret;
-           ret = FindMethodMore(ret, common_tagfunctions, self, a);
-           mylog(" %08x(%d) tag_getattr %s: %08x\n", (int)self, self->ob_refcnt, a, ret);
-           return ret;
-       }
+    if(tag->internals.tagfunctions) {
+       mylog(" %08x(%d) tag_getattr: tag has specific functions\n", (int)self, self->ob_refcnt);
+       ret = Py_FindMethod(tag->internals.tagfunctions, self, a);
+       if(ret) return ret;
+       PyErr_Clear();
+       ret = FindMethodMore(ret, common_tagfunctions, self, a);
+       mylog(" %08x(%d) tag_getattr %s: %08x\n", (int)self, self->ob_refcnt, a, ret);
+       if(ret) return ret;
+       PyErr_Clear();
     }
-   
+  
     ret = Py_FindMethod(common_tagfunctions, self, a);
 
     mylog(" %08x(%d) tag_getattr %s: %08x\n", (int)self, self->ob_refcnt, a, ret);
     return ret;
 }
+static int tag_setattr(PyObject * _self, char* a, PyObject * o)
+{
+    TagObject*self= (TagObject*)_self;
+    /* a setattr will almost certainly change the tag data,
+       so delete the tag */
+    if(self->internals.tag) {
+       swf_DeleteTag(self->internals.tag);
+       self->internals.tag = 0;
+    }
+    if(self->internals.setattr) {
+       int ret = self->internals.setattr(&self->internals, a, o);
+       return ret;
+    }
+    return 1;
+}
 //----------------------------------------------------------------------------
-//                     Tag Contructors
+//                     Tag Constructors
 //----------------------------------------------------------------------------
-PyObject* tag_new()
+PyObject* tag_new(tag_internals_t*tag_internals)
 {
     TagObject*tag = PyObject_New(TagObject, &TagClass);
     mylog("+%08x(%d) tag_new\n", (int)tag, tag->ob_refcnt);
-    tag->font = 0;
-    tag->character = 0;
-    tag->placeobject = 0;
-    tag->tag = 0;
-    tag->tagmap = tagmap_new();
+    memcpy(&tag->internals, tag_internals, sizeof(tag_internals_t));
+    if(tag->internals.datasize) {
+       tag->internals.data = malloc(tag->internals.datasize);
+       memset(tag->internals.data , 0, tag->internals.datasize);
+    } else {
+       tag->internals.data = 0;
+    }
+    tag->internals.tag = 0;
+    tag->internals.tagmap = tagmap_new();
+
     return (PyObject*)tag;
 }
 PyObject* tag_new2(TAG*t, PyObject* tagmap)
 {
     TagObject*tag = PyObject_New(TagObject, &TagClass);
-    mylog("+%08x(%d) tag_new tag=%08x\n", (int)tag, tag->ob_refcnt, t);
-    tag->font = 0;
-    tag->character = 0;
-    tag->placeobject = 0;
-    tag->tagmap = tagmap_new();
-    // copy tag
-    tag->tag = swf_InsertTag(0, t->id);
-    swf_SetBlock(tag->tag, t->data, t->len);
-    t = tag->tag;
+    mylog("+%08x(%d) tag_new2 tag=%08x id=%d (%s)\n", (int)tag, tag->ob_refcnt, t, t->id, swf_TagGetName(t));
     
+    PyObject*mytagmap = tagmap_new();
+
     int num = swf_GetNumUsedIDs(t);
-    int * positions = malloc(num*sizeof(int));
-    swf_GetUsedIDs(t, positions);
-    int i;
-    for(i=0;i<num;i++) {
-       int id = GET16(&t->data[positions[i]]);
-       PyObject*obj = tagmap_id2obj(tagmap, id);
-       if(obj==NULL) {
-           PyErr_SetString(PyExc_Exception, setError("TagID %d not defined", id));
-           return NULL;
+    if(num) { // tag has dependencies
+       int * positions = malloc(num*sizeof(int));
+       swf_GetUsedIDs(t, positions);
+       int i;
+       for(i=0;i<num;i++) {
+           int id = GET16(&t->data[positions[i]]);
+           PyObject*obj = tagmap_id2obj(tagmap, id);
+           if(obj==NULL) {
+               PyErr_SetString(PyExc_Exception, setError("TagID %d not defined", id));
+               return NULL;
+           }
+           //mylog("+%08x(%d) tag_new2 handling id %d at %d/%d\n", (int)tag, tag->ob_refcnt, id, positions[i], t->len);
+           //mylog("+%08x(%d) tag_new2 add dependency %d to id %d, object %08x(%d)\n", (int)tag, tag->ob_refcnt, i, id, obj, obj->ob_refcnt);
+           tagmap_addMapping(mytagmap, id, obj);
        }
-       tagmap_addMapping(tag->tagmap, id, obj);
-    }
-    free(positions);
-    return (PyObject*)tag;
-}
-
-static PyObject* f_SetBackgroundColor(PyObject* self, PyObject* args, PyObject* kwargs)
-{
-    static char *kwlist[] = {"color", NULL};
-    int r=0,g=0,b=0;
-    TagObject*tag;
-    PyObject*color;
-    
-    tag = (TagObject*)tag_new();
-
-    /* 1st try- copy constructor */
-    if(!PyArg_ParseTupleAndKeywords(args, kwargs, "O!", kwlist, &ColorClass, &color)) {
-       /* 2nd try- color's contructor */
-       color = f_Color(NULL, args, kwargs);
+       free(positions);
     }
-    if(!color)
-       return NULL;
-
-    tag->tag = swf_InsertTag(0, ST_SETBACKGROUNDCOLOR);
-    RGBA rgba = color_getRGBA(color);
-    swf_SetU8(tag->tag, rgba.r);
-    swf_SetU8(tag->tag, rgba.g);
-    swf_SetU8(tag->tag, rgba.b);
-    mylog(" %08x(%d) SetBackgroundColor(%02x,%02x,%02x) (colorobj=%08x(%d))\n", (int)tag, tag->ob_refcnt, rgba.r, rgba.g, rgba.b, color, color->ob_refcnt);
-    return (PyObject*)tag;
-}
-//----------------------------------------------------------------------------
-static PyObject* f_DefineFont(PyObject* self, PyObject* args, PyObject* kwargs)
-{
-    static char *kwlist[] = {"filename", NULL};
-    char*filename = 0;
-    TagObject*tag;
-    SWFFONT* font;
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", kwlist, &filename))
-       return NULL;
-
-    font = swf_LoadFont(filename);
-    if(!font) {
-       PyErr_SetString(PyExc_Exception, setError("Could not load %s", filename));
-       return NULL;
+    tag_internals_t*spec = get_parser(t->id);
+    if(spec) {
+       memcpy(&tag->internals, spec, sizeof(tag_internals_t));
+    } else {
+       memcpy(&tag->internals, &generic_tag, sizeof(tag_internals_t));
     }
-
-    tag = (TagObject*)tag_new();
-    tag->font = font;
-    tag->tag = swf_InsertTag(0, ST_DEFINEFONT2);
-    tag->font->id = 0;
-    swf_FontSetDefine2(tag->tag, tag->font);
-    mylog("+%08x(%d) DefineFont\n", (int)tag, tag->ob_refcnt);
-    return (PyObject*)tag;
-}
-static SWFFONT* fonttag_getSWFFONT(PyObject*self)
-{
-    PY_ASSERT_TYPE(self, &TagClass);
-    TagObject*font = (TagObject*)self;
-    return font->font;
-}
-//----------------------------------------------------------------------------
-static PyObject* f_Protect(PyObject* self, PyObject* args, PyObject* kwargs)
-{
-    static char *kwlist[] = {"password", NULL};
-    char*password = 0;
-    TagObject*tag;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", kwlist, &password))
-       return NULL;
-
-    tag = (TagObject*)tag_new();
-    tag->tag = swf_InsertTag(0, ST_PROTECT);
-    if(password) {
-       swf_SetPassword(tag->tag, password);
+    if(tag->internals.datasize) {
+       tag->internals.data = malloc(tag->internals.datasize);
+       memset(tag->internals.data, 0, tag->internals.datasize);
+    } else {
+       tag->internals.data = 0;
     }
-    mylog("+%08x(%d) f_Protect", (int)tag, tag->ob_refcnt);
-    return (PyObject*)tag;
-}
-//----------------------------------------------------------------------------
-static PyObject* f_DefineText(PyObject* self, PyObject* args, PyObject* kwargs)
-{
-    static char *kwlist[] = {"font", "text", "size", "color", NULL};
-    TagObject*tag = 0;
-    char*text = 0;
-    int textlen = 0;
-    PyObject*unicode16;
-    PyObject*unicode8;
-    int size = 0;
-    RGBA rgba = {255,0,0,0};
-    PyObject*color = 0;
-    PyObject*font = 0;
-    SRECT r;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!u#i|O!", kwlist, &TagClass, &font, &text, &textlen, &size, &ColorClass, &color))
-       return NULL;
-    
-    unicode16 = PyUnicode_DecodeUTF16(text, textlen*2, NULL, NULL);
-    unicode8 = PyUnicode_AsUTF8String(unicode16);
-    text = PyString_AS_STRING(unicode8);
-
-    if(color)
-       rgba = color_getRGBA(color);
+    tag->internals.tag = swf_InsertTag(0, t->id);
+    swf_SetBlock(tag->internals.tag, t->data, t->len);
+    tag->internals.tagmap = mytagmap;
 
-    mylog("DefineText: text = %s", text);
-    
-    tag = (TagObject*)tag_new();
-
-    int font_id = tagmap_add(tag->tagmap, font); // add dependency on font
-
-    fonttag_getSWFFONT(font)->id = font_id;
-
-    tag ->tag= swf_InsertTag(0, ST_DEFINETEXT2);
-    swf_SetU16(tag->tag, /*ID*/0);
-    r = swf_SetDefineText(tag->tag, fonttag_getSWFFONT(font), &rgba, text, size);
-    mylog("+%08x(%d) DefineText tag=%08x \n", (int)tag, tag->ob_refcnt);
-    
-    //Py_DECREF(unicode16);
-    //Py_DECREF(unicode8);
-    //free(text);
+    // call tag->internals.init()?
 
     return (PyObject*)tag;
 }
 //----------------------------------------------------------------------------
-static PyObject* f_PlaceObject(PyObject* self, PyObject* args, PyObject* kwargs)
-{
-    static char *kwlist[] = {"character", "depth", "matrix", "colortransform", "ratio", "name", "clipdepth", "action", NULL};
-    TagObject*tag;
-    
-    TagObject*character = 0;
-    int depth;
-    int clipdepth = 0;
-    PyObject*matrix = 0;
-    PyObject*cxform = 0;
-    PyObject*action = 0;
-    int ratio = 0;
-    char* name = 0;
-    SWFPLACEOBJECT* po;
-    po = malloc(sizeof(SWFPLACEOBJECT));
-    memset(po, 0, sizeof(SWFPLACEOBJECT));
-
-    swf_GetPlaceObject(0, po);
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!i|O!O!isiO!", kwlist, 
-               &TagClass, &character, 
-               &depth, 
-               &MatrixClass, &matrix, 
-               &CXFormClass, &cxform,
-               &ratio,
-               &name,
-               &clipdepth,
-               &ActionClass, &action
-               ))
-       return NULL;
-    po->depth = depth;
-    po->id = /*ID*/ 0;
-    po->clipdepth = clipdepth;
-    po->ratio = ratio;
-    po->name = name;
-    if(clipdepth) po->clipdepth = clipdepth;
-    if(matrix) po->matrix = matrix_getMatrix(matrix);
-    if(cxform) po->cxform = colortransform_getCXForm(cxform);
-    if(action) po->actions = action_getAction(action);
-
-    tag = (TagObject*)tag_new();
-    tag->placeobject = po;
-    Py_INCREF(character);
-    tag->character = (PyObject*)character;
-    tag->tag= swf_InsertTag(0, ST_PLACEOBJECT2);
-
-    po->id = tagmap_add(tag->tagmap,(PyObject*)character);
-
-    swf_SetPlaceObject(tag->tag, po);
-    mylog("+%08x(%d) PlaceObject %08x(%d)\n", (int)tag, tag->ob_refcnt, character, character->ob_refcnt);
-
-    return (PyObject*)tag;
-}
-
 /* serialize */
 TAG* tag_getTAG(PyObject*self, TAG*prevTag, PyObject*tagmap)
 {
     TagObject*tag = (TagObject*)self;
-    
-    mylog(" %08x(%d) tag_getTAG: tag=%08x id=%d (%s)", (int)self, self->ob_refcnt, tag->tag, tag->tag->id, swf_TagGetName(tag->tag));
 
-    TAG* t = swf_InsertTag(prevTag, tag->tag->id);
-    swf_SetBlock(t, tag->tag->data, tag->tag->len);
+    if(!fillTAG(self))
+       return 0;
+    mylog(" %08x(%d) tag_getTAG: tag=%08x id=%d (%s)", (int)self, self->ob_refcnt, tag->internals.tag, tag->internals.tag->id, swf_TagGetName(tag->internals.tag));
+
+    TAG* t = swf_InsertTag(prevTag, tag->internals.tag->id);
+    swf_SetBlock(t, tag->internals.tag->data, tag->internals.tag->len);
     
     if(swf_isDefiningTag(t)) {
        int newid = tagmap_add(tagmap, self);
@@ -358,37 +286,60 @@ TAG* tag_getTAG(PyObject*self, TAG*prevTag, PyObject*tagmap)
     }
 
     int num = swf_GetNumUsedIDs(t);
-    int * positions = malloc(num*sizeof(int));
-    swf_GetUsedIDs(t, positions);
-    int i;
-    for(i=0;i<num;i++) {
-       int id = GET16(&t->data[positions[i]]);
-       PyObject* obj =  tagmap_id2obj(tag->tagmap, id);
-       if(obj==NULL) {
-           PyErr_SetString(PyExc_Exception, setError("Internal error: id %d not known in taglist:"));
-           free(positions);
-           return 0;
+    if(num) { // tag has dependencies
+       int * positions = malloc(num*sizeof(int));
+       swf_GetUsedIDs(t, positions);
+       int i;
+       for(i=0;i<num;i++) {
+           int id = GET16(&t->data[positions[i]]);
+           PyObject* obj =  tagmap_id2obj(tag->internals.tagmap, id);
+           if(obj==NULL) {
+               PyErr_SetString(PyExc_Exception, setError("Internal error: id %d not known in taglist:"));
+               free(positions);
+               return 0;
+           }
+           //int newid = tagmap_obj2id(tag->internals.tagmap, obj);
+           int newid = tagmap_obj2id(tagmap, obj);
+           if(newid>=0) {
+               mylog(" %08x(%d) tag_getTAG: dependency %d) %d->%08x -> assigning(%08x) id %d", (int)self, self->ob_refcnt, i, id, obj, tagmap, newid);
+           } else {
+               /* TODO: this is only needed for sprites, so maybe it should throw an
+                  exception otherwise */
+               newid = tagmap_add(tagmap, obj);
+               mylog(" %08x(%d) tag_getTAG: added dependency %d) %d->%08x -> assigning(%08x) id %d", (int)self, self->ob_refcnt, i, id, obj, tagmap, newid);
+           }
+           PUT16(&t->data[positions[i]], newid);
        }
-       int newid = tagmap_obj2id(tagmap, obj);
-       PUT16(&t->data[positions[i]], newid);
+       free(positions);
     }
-    free(positions);
     return t;
 }
-
+//----------------------------------------------------------------------------
+tag_internals_t* tag_getinternals(PyObject*self)
+{
+    TagObject*tag = (TagObject*)self;
+    mylog(" %08x(%d) tag_getInternals\n", (int)self, self->ob_refcnt);
+    return &tag->internals;
+}
+//----------------------------------------------------------------------------
 PyObject* tag_getDependencies(PyObject*self)
 {
     TagObject*tag = (TagObject*)self;
-    mylog(" %08x(%d) tag_getDependencies id=%d tag=%s\n", (int)self, self->ob_refcnt, tag->tag->id, swf_TagGetName(tag->tag));
-    return tagmap_getObjectList(tag->tagmap);
+    mylog(" %08x(%d) tag_getDependencies\n", (int)self, self->ob_refcnt);
+    return tagmap_getObjectList(tag->internals.tagmap);
 }
-
-int tag_print (PyObject * self, FILE * fi, int flags)
+//----------------------------------------------------------------------------
+int tag_print(PyObject * self, FILE * fi, int flags)
 {
+    TagObject*tag = (TagObject*)self;
     mylog(" %08x(%d) tag_print flags=%08x\n", (int)self, self->ob_refcnt, flags);
+    if(!fillTAG(self))
+       return -1;
+    //fprintf(fi, "tag-%08x-%d-%s", (int)tag->internals.tag, tag->internals.tag->id, swf_TagGetName(tag->internals.tag));
+    fprintf(fi, "%s", swf_TagGetName(tag->internals.tag));
     return 0;
 }
-
+//----------------------------------------------------------------------------
 PyTypeObject TagClass = 
 {
     PyObject_HEAD_INIT(NULL)
@@ -399,20 +350,5 @@ PyTypeObject TagClass =
     tp_dealloc: tag_dealloc,
     tp_print: tag_print,
     tp_getattr: tag_getattr,
+    tp_setattr: tag_setattr,
 };
-static PyMethodDef TagMethods[] = 
-{
-    /* TAGS */
-    {"SetBackgroundColor", (PyCFunction)f_SetBackgroundColor, METH_KEYWORDS, "Create a SetBackGroundColor Tag."},
-    {"Protect", (PyCFunction)f_Protect, METH_KEYWORDS, "Create a Protect Tag."},
-    {"DefineFont", (PyCFunction)f_DefineFont, METH_KEYWORDS, "Create a DefineFont Tag."},
-    {"DefineText", (PyCFunction)f_DefineText, METH_KEYWORDS, "Create a DefineText Tag."},
-    {"PlaceObject", (PyCFunction)f_PlaceObject, METH_KEYWORDS, "Create a PlaceObject Tag."},
-    {NULL, NULL, 0, NULL}
-};
-PyMethodDef* tag_getMethods()
-{
-    TagClass.ob_type = &PyType_Type;
-    return TagMethods;
-}
-