swfobjectGenerator = function()
{
  var UNDEF = "undefined", OBJECT = "object", FLASH_MIME_TYPE = "application/x-shockwave-flash", win = window, doc = document, nav = navigator;  
  var ua = (function(){
    var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF;
    var u = nav.userAgent.toLowerCase(),
      p = nav.platform.toLowerCase(),
      webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, // returns either the webkit version or false if not webkit
      ie = false,
      windows = p ? /win/.test(p) : /win/.test(u),
      mac = p ? /mac/.test(p) : /mac/.test(u);
      /*@cc_on
        ie = true;
	@if (@_win32)
	  windows = true;
	@elif (@_mac)
	  mac = true;
	@end
      @*/
    return { ie:ie, win:win, mac: mac, webkit: webkit, w3cdom: w3cdom };
  })();

  function prepareAttributes(attObj, swfUrlStr, widthStr, heightStr) {
    var att = {};
    if (attObj && typeof attObj === OBJECT) {
      for (var i in attObj) {
	if (attObj[i] != Object.prototype[i]) { // Filter out prototype additions from other potential libraries
	  att[i] = attObj[i];
	}
      }
    }
    att.data = swfUrlStr;
    att.width = widthStr;
    att.height = heightStr;
    return att;
  }

  function prepareParameters(parObj, flashvarsObj) {
    var par = {}; 
    if (parObj && typeof parObj === OBJECT) {
      for (var j in parObj) {
	if (parObj[j] != Object.prototype[j]) { // Filter out prototype additions from other potential libraries
	  par[j] = parObj[j];
	}
      }
    }
    if (flashvarsObj && typeof flashvarsObj === OBJECT) {
      for (var k in flashvarsObj) {
	if (flashvarsObj[k] != Object.prototype[k]) { // Filter out prototype additions from other potential libraries
	  if (typeof par.flashvars != UNDEF) {
	    par.flashvars += "&" + k + "=" + flashvarsObj[k];
	  }
	  else {
	    par.flashvars = k + "=" + flashvarsObj[k];
	  }
	}
      }
    }
    return par;
  }

  function createSWF(attObj, parObj){
    var retval;
    if (ua.ie && ua.win)
      retval = generateHTMLPiecesForIE(attObj, parObj)
    else
      retval = generateHTMLPiecesForGoodBrowsers(attObj, parObj);
    var att = generateAttributes(retval.att);
    var par = generateParameters(retval.par);
    
    
    return '<object' + att + '>' + par + '</object>';
  }

  function generateHTMLPiecesForIE(attObj, parObj)
  {
    if(typeof attObj.data !== UNDEF)
    {
      parObj.movie = attObj.data;
      delete attObj.data;
    }
    if(typeof attObj['styleclass'] !== UNDEF)
    {
      attObj['class'] = attObj['styleclass'];
      delete attObj['styleclass'];
    }
    
    attObj.classid = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000';

    return {att: attObj, par: parObj};
  }

  function generateHTMLPiecesForGoodBrowsers(attObj, parObj) {
    attObj.type = FLASH_MIME_TYPE;
    if(typeof attObj['styleclass'] !== UNDEF)
    {
      attObj['class'] = attObj['styleclass'];
      delete attObj['styleclass'];
    }
    if(typeof attObj.classid !== UNDEF)
      delete attObj.classid;

    return {att: attObj, par: parObj};
  }

  function generateAttributes(attObj) {
    var att = "";
    for (var i in attObj) {
      if (attObj[i] != Object.prototype[i]) { // Filter out prototype additions from other potential libraries, like Object.prototype.toJSONString = function() {}
        att += ' ' + i + '="' + attObj[i] + '"';
      }
    }
    return att;
  }

  function generateParameters(parObj) {
    var par = "";
    for (var i in parObj) {
      if (parObj[i] != Object.prototype[i]) { // Filter out prototype additions from other potential libraries
	par += '<param name="' + i + '" value="' + parObj[i] + '" />';
      }
    }
    return par;
  }

  return {    
    generate: function(url, width, height, flashvars, params, attributes)
    {    
      var att = prepareAttributes(attributes, url, width, height);
      var par = prepareParameters(params, flashvars);
      return createSWF(att, par);
    }
  };
}
