function FlashTag(src, width, height, version) {
    if (arguments.length < 4)
    {
        throw new Exception('RequiredAttributeException',
                            'You must pass in a src, width, height, and version when creating a FlashTag.');
    }

    for (var i = 0; i < arguments.length; ++i)
    {
        if (arguments[i] == undefined || arguments[i] == null)
        {
            throw new Exception('RequiredAttributeException',
                                'All constructor arguments must have values.');
        }
    }

    // Required
    this.src            =  src;
    this.width          =  width;
    this.height         =  height;
    this.version        =  version;

    this.id             =  null;
    this.flashVars      =  null;
    this.flashVarsStr   =  null;
    this.genericParam   = new Object();
    this.ie = (navigator.appName.indexOf ("Microsoft") != -1) ? 1 : 0;
}
FlashTag.prototype.setSource = function(src) {
    this.src = src;
}
FlashTag.prototype.setWidth = function(w) {
    this.width = width;
}
FlashTag.prototype.setHeight = function(h) {
    this.h = height;
}
FlashTag.prototype.setVersion = function(v) {
    this.version = v;
}
FlashTag.prototype.setId = function(id) {
    this.id = id;
}
FlashTag.prototype.setBgcolor = function(bgc) {
    if (bgc.charAt(0) != '#') bgc = '#' + bgc;
    this.genericParam['bgcolor'] = bgc;
}
FlashTag.prototype.addFlashVars = function(fvs) {
    this.flashVarsStr = fvs;
}
FlashTag.prototype.addFlashVar = function(n, v) {
    if (this.flashVars == null) this.flashVars = new Object();
    this.flashVars[n] = v;
}
FlashTag.prototype.removeFlashVar = function(n) {
    if (this.flashVars != null) this.flashVars[n] = undefined;
}
FlashTag.prototype.setSwliveconnect = function(swlc) {
    this.genericParam['swliveconnect'] = swlc;
}
FlashTag.prototype.setPlay = function(p) {
    this.genericParam['play'] = p;
}
FlashTag.prototype.setLoop = function(l) {
    this.genericParam['loop'] = l;
}
FlashTag.prototype.setMenu = function(m) {
    this.genericParam['menu'] = m;
}
FlashTag.prototype.setQuality = function(q) {
    if (q != 'low' && q != 'high' && q != 'autolow' && q != 'autohigh' && q != 'best')
    {
        throw new Exception('UnsupportedValueException',
                            'Supported values are "low", "high", "autolow", "autohigh", and "best".');
    }
    this.genericParam['quality'] = q;
}
FlashTag.prototype.setScale = function(sc) {
    if (sc != 'showall' && sc != 'noborder' && sc != 'exactfit' && sc != 'noscale')
    {
        throw new Exception('UnsupportedValueException',
                            'Supported values are "showall", "noborder", "exactfit, and "noscale".');
    }
    this.genericParam['scale'] = sc;
}
FlashTag.prototype.setAlign= function(a) {
    if (a != 'l' && a != 't' && a != 'r' && a != 'b')
    {
        throw new Exception('UnsupportedValueException',
                            'Supported values are "l", "t", "r" and "b".');
    }
    this.genericParam['align'] = a;
}
FlashTag.prototype.setSalign= function(sa) {
    if (sa != 'l' && sa != 't' && sa != 'r' && sa != 'b' && sa != 'tl' && sa != 'tr' && sa != 'bl' && sa != 'br')
    {
        throw new Exception('UnsupportedValueException',
                            'Supported values are "l", "t", "r", "b", "tl", "tr", "bl" and "br".');
    }
    this.genericParam['salign'] = sa;
}
FlashTag.prototype.setWmode = function(wm) {
    if (wm != 'window' && wm != 'opaque' && wm != 'transparent')
    {
        throw new Exception('UnsupportedValueException',
                            'Supported values are "window", "opaque", and "transparent".');
    }
    this.genericParam['wmode'] = wm;
}
FlashTag.prototype.setBase = function(base) {
    this.genericParam['base'] = base;
}
FlashTag.prototype.toString = function() {
    var flashTag = new String();
    if (this.ie)
    {
        flashTag += '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ';
        if (this.id != null)
        {
            flashTag += 'id="'+this.id+'" ';
        }
        flashTag += 'codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version='+this.version+'" ';
        flashTag += 'width="'+this.width+'" ';
        flashTag += 'height="'+this.height+'">';
        flashTag += '<param name="movie" value="'+this.src+'"/>';

        for (var n in this.genericParam)
        {
            if (this.genericParam[n] != undefined && this.genericParam[n] != null)
            {
                flashTag += '<param name="'+n+'" value="'+this.genericParam[n]+'"/>';
            }
        }

        if (this.flashVars != null)
        {
            var fv = this.getFlashVarsAsString();
            if (fv.length > 0)
            {
                flashTag += '<param name="flashvars" value="'+fv+'"/>';
            }
        }
        flashTag += '</object>';
    }
    else
    {
        flashTag += '<embed src="'+this.src+'"';
        flashTag += ' width="'+this.width+'"';
        flashTag += ' height="'+this.height+'"';
        flashTag += ' type="application/x-shockwave-flash"';
        if (this.id != null)
        {
            flashTag += ' name="'+this.id+'"';
        }

        for (var n in this.genericParam)
        {
            if (this.genericParam[n] != undefined && this.genericParam[n] != null)
            {
                flashTag += (' '+n+'="'+this.genericParam[n]+'"');
            }
        }
        if (this.flashVars != null || this.flashVarsStr != null)
        {
            var fv = this.getFlashVarsAsString();
            if (fv.length > 0)
            {
                flashTag += ' flashvars="'+fv+'"';
            }
        }
        flashTag += ' pluginspage="http://www.macromedia.com/go/getflashplayer">';
        flashTag += '</embed>';
    }
    return flashTag;
}
FlashTag.prototype.write = function(doc) {
    doc.write(this.toString());
}
FlashTag.prototype.getFlashVarsAsString = function() {
    var qs = new String();
    for (var n in this.flashVars)
    {
        if (this.flashVars[n] != undefined && this.flashVars[n] != null)
        {
            qs += (escape(n)+'='+escape(this.flashVars[n])+'&');
        }
    }

    if (this.flashVarsStr != null) return qs + this.flashVarsStr;

    return qs.substring(0, qs.length-1);
}
FlashTag.prototype.setParams = function( id, bgc, fvs, swlc, p, l, m, q, sc, a, wm, base ) {
    if (id != null) this.id             =  id;
    if (fvs != null) this.flashVarsStr   =  fvs;

    if (bgc != null) this.setBgcolor(bgc);
    if (swlc != null) this.setSwliveconnect(swlc);
    if (p != null) this.setPlay(p);
    if (l != null) this.setLoop(l);
    if (m != null) this.setMenu(m);
    if (q != null) this.setQuality(q);
    if (sc != null) this.setScale(sc);
    if (a != null) this.setAlign(a);
    if (wm != null) this.setWmode(wm);
    if (base != null) this.setBase(base);
}
