if( ! Ice )
{

var Ice = new Object();
Ice.Strings = new Object();
Ice.Widget = new Object();

// *****************************************************************************
// * configuration object (singleton)
// *****************************************************************************

Ice.Conf = new function ()
{
  this.include_css       = new Array ("ext-all.css");
  this.include_pre_data  = new Array ("ext-base-debug.js","ext-all-debug.js","RowExpander.js","ice-bug.js","ice-messages.js");
  this.include_post_data = new Array ("ice-popup.js","ice-pages.js","ice-microsite.js");

  // Locations of widget resources
  //// LIVE
  this.Root = "http://demos.ice-ol.com/";
  //// DEV
  //this.Root = "/";
  
  this.WidgetRoot = this.Root+"widget/";
  this.ImgsRoot   = this.WidgetRoot+"images/";
  
  var prepend = function (str, array)
  {
    for(var i = 0; i < array.length; i++)
    {
      array[i] = str+array[i];
    }
  }
  
  prepend(this.WidgetRoot, this.include_css);
  prepend(this.WidgetRoot, this.include_pre_data);
  prepend(this.WidgetRoot, this.include_post_data);
  
  this.MessagesRoot    = "http://v1.demo.ice-ol.com/Messages/";
  
  // the elemment to which Ice should attach
  this.IceClass = "ice-enabled";

} ();

// *****************************************************************************
// * util methods (singleton)
// *****************************************************************************

Ice.Utils = new function ()
{
  // ===========================================================================
  // = cookie access

  this.get_cookie = function (name)
  {
    //alert('heres the whole cookie: '+document.cookie);

    var crumbs = document.cookie.split('; ');

    for(var i = 0; i < crumbs.length; i++)
    {
      var kv = crumbs[i].split('=');

      if(kv[0] == name)
      {
        return kv[1];
      }
    }

    return false;
  }

  // ==============================================================================
  // = load functions (asynchronous)

  this.async_js_load = function (url)
  {
    var head = document.getElementsByTagName("head")[0];

    var new_js = document.createElement('script');
    new_js.setAttribute( 'type', 'text/javascript' );
    new_js.setAttribute( 'src',  url );

    head.appendChild(new_js);
  };

  this.async_css_load = function (url)
  {
    var head = document.getElementsByTagName("head")[0];

    var new_css = document.createElement('link');
    new_css.setAttribute( 'rel', 'stylesheet' );
    new_css.setAttribute( 'type', 'text/css' );
    new_css.setAttribute( 'href',  url );

    head.appendChild(new_css);
  };

} ();

// *****************************************************************************
// * chain loader (singleton)
// *****************************************************************************
// this allows synchronous loading of js plus a callback after it's all done
// also, this allows tracking of what is loaded
// note that all js loaded this way must have some chainloading code
//   (an if() statement surrounding all the code)

Ice.ChainLoader = new function ()
{
  this.chain = [];
  this.chain_done = true;

  this.load_chain = function (list, callback, callback_obj)
  {
    this.chain = list;
    this.chain_done = false;

    this.cb  = callback;
    this.cbo = callback_obj;

    this.next();
  };

  this.next = function ()
  {
    if( this.chain.length > 0 )
    {
      var link = this.chain.shift();

      //alert('starting to load '+link);

      Ice.Utils.async_js_load(link);
    }
    else
    {
      //alert('chain done');

      this.chain_done = true;

      this.cb(this.cbo);
    }
  };

  this.is_chain_done = function ()
  {
    return this.chain_done;
  };
  
  // ===========================================================================
  // = load tracking functions

  this.registered = new Array();

  this.register = function (id)
  {
    this.registered[id] = true;
  }

  this.is_registered = function (id)
  {
    if( this.registered[id] && this.registered[id] == true )
    {
      return true;
    }
    else
    {
      return false;
    }
  }

} ();

// *****************************************************************************
// * widget object
// *****************************************************************************

Ice.Widget = function ()
//Ice.Main = new function ()
{
  this.init = function (ad_element)
  //this.init = function (ad_element, iid)
  {
    // ad on which this widget is attached
    this.ad  = ad_element;

    // id of the ad mapping to a specific set of widget content
    this.id  = this.ad.dom.getAttribute('ice-id');

    // id of this user-widget interation
    this.xid = ''+Ice.Utils.get_cookie('widgetIDSeed')+this.id+new Date().getTime()+Math.round(Math.random() * 1000000);
    //this.xid = iid;

    // collection of all "bugs" (little icon things)
    this.bugs = new Array();
    this.add_bug(ad_element);

    this.messenger = new Ice.Widget.Messages(this);
  }
  
  // this method adds a bug onto an element
  this.add_bug = function (ad_element)
  {
    var bug_obj = new Object();
    
    bug_obj.ad  = ad_element;
    bug_obj.id  = this.bugs.length;
    bug_obj.bug = new Ice.Widget.Bug(this, bug_obj);
    bug_obj.bug.init();
    
    this.bugs.push(bug_obj);
  }
  
  this.set_data = function (loaded_data)
  {
    this.data = loaded_data;
  }
  
  this.process_data = function ()
  {
    this.lang = Ice.Strings[this.data.language];
    
    // each HTMLelement that a bug is associated with needs a popup too
    this.popups = new Array();
    for(var i = 0; i < this.bugs.length; i++)
    {
      var popup_obj = new Object();
      
      popup_obj.ad    = this.bugs[i].ad;
      popup_obj.popup = new Ice.Widget.Popup(this, popup_obj);
      popup_obj.popup.init();
      
      this.popups.push(popup_obj);
    }
    
    this.microsite = new Ice.Widget.Microsite(this);
    this.microsite.init();
  }

};
//} ();

// *****************************************************************************
// * init functions
// *****************************************************************************

// hash containing all widgets on the page
Ice.widgets = new Object();

Ice.init_1 = function ()
{
  // load css
    for(var i = 0; i < Ice.Conf.include_css.length; i++)
    {
      Ice.Utils.async_css_load( Ice.Conf.include_css[i] );
    }
  
  // load pre-js
    Ice.ChainLoader.load_chain( Ice.Conf.include_pre_data, function (o) { o.init_2(); }, Ice );
}

Ice.init_2 = function ()
{
  // init EXT
    Ext.BLANK_IMAGE_URL = Ice.Conf.ImgsRoot + 'default/s.gif';
    Ext.QuickTips.init();
    Ext.useShims = false;
    //Ext.form.Field.prototype.msgTarget = 'qtip';
    Ext.form.TextField.prototype.selectOnFocus = true;
    //Ext.form.TextField.prototype.grow = false;
    //Ext.form.TextField.prototype.xtype = 'textfield';
  
  // initialize initialization of widget objects
    var divs = Ext.select('.'+Ice.Conf.IceClass, true);
    
    // for each, init a widget and store said widget so it can be easily referenced later
    for(var i = 0; i < divs.getCount(); i++)
    {
      var ice_element = divs.item(i);
      var ice_id      = ice_element.dom.getAttribute('ice-id');
      
      if( Ice.widgets[ice_id] )
      {
        Ice.widgets[ice_id].add_bug(ice_element);
      }
      else
      {
        var widget = new Ice.Widget();
        widget.init(ice_element);
        
        Ice.widgets[ice_id] = widget;
      }
    }
  
  // load post-js
    Ice.ChainLoader.load_chain( Ice.Conf.include_post_data, function (o) { o.init_3(); }, Ice );
}

Ice.init_3 = function ()
{
  // start JSON call on all widget objects
    for(widget_key in Ice.widgets)
    {
      Ice.widgets[widget_key].messenger.data_message();
    }
}

// catch call-back from JSON messages
Ice.init_data = function (id, data)
{
  // first make sure there is a language set
  if( ! data.language )
  {
    data.language = 'EN';
  }
  
  // associate this data with its widget
  Ice.widgets[id].set_data(data);
  
  // now check to see if all data has been loaded
  // TODO: this part can be done better without the loop every time
  var all_data_loaded = true;
  
  for(widget_key in Ice.widgets)
  {
    if( ! Ice.widgets[widget_key].data )
    {
      all_data_loaded = false;
      break;
    }
  }
  
  if( all_data_loaded )
  {
    var languages_hash = new Object();
    
    for(widget_key in Ice.widgets)
    {
      languages_hash[Ice.widgets[widget_key].data.language] = true;
    }
    
    var language_files_array = new Array();
    
    for(language in languages_hash)
    {
      language_files_array.push(Ice.Conf.WidgetRoot+'ice-strings.'+language+'.js')
    }
    
    Ice.ChainLoader.load_chain( language_files_array, function (o) { o.finish_init_data(); }, Ice );
  }
}

Ice.finish_init_data = function ()
{
  for(widget_key in Ice.widgets)
  {
    Ice.widgets[widget_key].process_data();
  }
}

// *****************************************************************************
// * onload hook
// *****************************************************************************

// back up old onload function so as to play nice
if( typeof onload == 'function' )
{
  Ice.oldonload = onload;
}
else
{
  Ice.oldonload = false;
}

if( Ice.oldonload )
{
  onload = function ()
  {
    Ice.oldonload();
    
    // start the load chain for the widget
    Ice.init_1();
  }
}
else
{
  onload = function ()
  {
    Ice.init_1();
  }
}

}
