function GuiItemBase(domNode,
                     initialData,
                     stateInfos,
                     initialStateId,
                     callBackObject)
{
  this.getState =
  function()  
  {
    return _state;
  };

  this.setState =
  function(state)
  {
    if(state == _state){
      return 1;  
    }  

    for(var i in _stateInfos){
      if(_stateInfos[i].getStateId() == state){

        var stateInfo = _getStateInfo();  

        if(stateInfo !== null && stateInfo.getStateType() != GuiItemBase.StateInfo.STATE_TYPE_ACTIVE){ 
          _stopMouseDownCallbacks();
        }

        _state = state;
      
        for(var i in _stateChangeCBFs){
          _stateChangeCBFs[i](_cbo);
        }

        return 1;
      }
    }
    return 0;
  };

  this.getCallBackObject =
  function()
  {
    return _cbo;  
  };

  this.getStateInfo =
  function()
  {
    return _getStateinfo();
  };

  this.getData =
  function()
  {
    return _data;
  };

  this.setData =
  function(data)
  {
    _data = data;
  };

  this.getDomNode =
  function()
  {
    return _domNode;
  };

  this.getMouseOver =
  function()
  {
    return _mouseOver;
  };

  this.getMouseDown =
  function()
  {
    return _mouseDown;
  };

  this.getMouseState =
  function()
  {
    return _mouseState;  
  };

  this.addStateChangeCBF =
  function(cbf)
  {
    _stateChangeCBFs.push(cbf);
  };

  this.addMouseClickCBF =
  function(cbf)
  {
    _mouseClickCBFs.push(cbf);
  };

  this.addMouseEnterCBF =
  function(cbf)
  {
    _mouseEnterCBFs.push(cbf);
  };

  this.addMouseLeaveCBF =
  function(cbf)
  {
    _mouseLeaveCBFs.push(cbf);
  };

  this.addMousePressCBF =
  function(cbf)
  {
    _mousePressCBFs.push(cbf);
  };

  this.addMouseReleaseCBF =
  function(cbf)
  {
    _mouseReleaseCBFs.push(cbf);
  };

  this.addMouseDownCBF =
  function(cbf, interval)  
  {
    _mouseDownCBFs.push({'CBF' : cbf,
                         'interval' : interval,
                         'timer' : null});
  };

  /* Private part below! */	

  var _getStateInfo =
  function()
  {
    for(var i in _stateInfos){  
      if(_stateInfos[i].getStateId() == _state){
        return _stateInfos[i];  
      }
    }
    return null;
  };

  var _mouseDownCallBackObject =
  function(cbf, cbo)
  {
    var _cbf = cbf;
    var _cbo = cbo;
    
    return function()
    {
      _cbf(_cbo);
    };
  };

  var _startMouseDownCallbacks =
  function()
  {
    for(var i in _mouseDownCBFs){
      
      _mouseDownCBFs[i]['timer'] = 
      setInterval(new _mouseDownCallBackObject(_mouseDownCBFs[i]['CBF'], _cbo),
                                               _mouseDownCBFs[i]['interval']);
    } 
  };

  var _stopMouseDownCallbacks =
  function()
  {
    for(var i in _mouseDownCBFs){
     
      if(_mouseDownCBFs[i]['timer'] !== null){
        clearInterval(_mouseDownCBFs[i]['timer']);
        _mouseDownCBFs[i]['timer'] = null;
      }
    }
  };
  
  var _this = this;
  var _domNode = domNode;
  var _data = initialData;
  var _state = initialStateId;
  var _stateInfos = stateInfos;
  var _cbo = callBackObject;

  var _mouseOver = false;
  var _mouseDown = false;

  var _mouseState = GuiItemBase.MOUSE_STATE_NO_MOUSE;

  var _mouseClickCBFs = new Array();
  var _mouseDownCBFs = new Array();
  var _mouseEnterCBFs = new Array();
  var _mouseLeaveCBFs = new Array();
  var _mousePressCBFs = new Array();
  var _mouseReleaseCBFs = new Array();

  var _stateChangeCBFs = new Array();

  _domNode.onclick =
  function()
  {
    var stateInfo = _getStateInfo();  

    if(stateInfo !== null && stateInfo.getStateType() == GuiItemBase.StateInfo.STATE_TYPE_ACTIVE){

      for(var i in _mouseClickCBFs){
        _mouseClickCBFs[i](_this);
      }
    }
  };

  _domNode.onmousedown = 
  function()
  {
    _mouseDown = true;
    _mouseState = GuiItemBase.MOUSE_STATE_MOUSE_DOWN;

    var stateInfo = _getStateInfo();  

    if(stateInfo !== null && stateInfo.getStateType() == GuiItemBase.StateInfo.STATE_TYPE_ACTIVE){

      for(var i in _mousePressCBFs){
        _mousePressCBFs[i](_cbo);
      }

      _startMouseDownCallbacks();
    }
  };

  _domNode.onmouseup =
  function()
  {
    _mouseDown = false;
    _mouseState = GuiItemBase.MOUSE_STATE_MOUSE_OVER;

    var stateInfo = _getStateInfo();  

    if(stateInfo !== null && stateInfo.getStateType() == GuiItemBase.StateInfo.STATE_TYPE_ACTIVE){

      _stopMouseDownCallbacks();

      for(var i in _mouseReleaseCBFs){
        _mouseReleaseCBFs[i](_cbo);
      }
    }
  };

  _domNode.onmouseover =
  function()
  {
    if(_mouseOver !== true){

      _mouseOver = true;
      _mouseState = GuiItemBase.MOUSE_STATE_MOUSE_OVER;

      var stateInfo = _getStateInfo();  

      if(stateInfo !== null && stateInfo.getStateType() == GuiItemBase.StateInfo.STATE_TYPE_ACTIVE){

        for(var i in _mouseEnterCBFs){
          _mouseEnterCBFs[i](_cbo);
        }
      }
    }
  };

  _domNode.onmouseout =
  function()
  {
    _mouseOver = false;
    _mouseDown = false;

    _mouseState = GuiItemBase.MOUSE_STATE_NO_MOUSE;

    var stateInfo = _getStateInfo();  

    if(stateInfo !== null && stateInfo.getStateType() == GuiItemBase.StateInfo.STATE_TYPE_ACTIVE){

      for(var i in _mouseLeaveCBFs){
        _mouseLeaveCBFs[i](_cbo);
      }

      _stopMouseDownCallbacks();
    }
  };
  

  
  _domNode.onkeyup =
  function(evt)
  { 
    var keyCode = null;

    if(evt){
      if(evt.keyCode){
        keyCode = evt.keyCode;
      }
    }
    else if(event){
      if(event.keyCode){
        keyCode = event.keyCode;  
      }
    }

    if(keyCode == 13){ /* enter */

      var stateInfo = _getStateInfo();   

      if(stateInfo !== null && stateInfo.getStateType() == GuiItemBase.StateInfo.STATE_TYPE_ACTIVE){
     
        for(var i in _mouseClickCBFs){
          _mouseClickCBFs[i](_cbo);
        }
      }
    }
  };
};

GuiItemBase.MOUSE_STATE_NO_MOUSE = 1;
GuiItemBase.MOUSE_STATE_MOUSE_OVER = 2;
GuiItemBase.MOUSE_STATE_MOUSE_DOWN = 3;


GuiItemBase.StateInfo =
function(stateId, stateType)
{
  this.getStateId =
  function()
  {
    return _stateId;  
  }

  this.getStateType =
  function()
  {
    return _stateType;  
  }

  var _stateId = stateId;
  var _stateType = stateType;    
};

GuiItemBase.StateInfo.STATE_TYPE_ACTIVE = 1;
GuiItemBase.StateInfo.STATE_TYPE_PASSIVE = 2;



GuiItemBase.StyleManager =
function(styles)
{
  this.addGuiItem =
  function(guiItem)
  {
    _changeStyle(guiItem); 

    guiItem.addStateChangeCBF(_changeStyle);
    guiItem.addMouseEnterCBF(_changeStyle);
    guiItem.addMouseLeaveCBF(_changeStyle);
    guiItem.addMousePressCBF(_changeStyle);
    guiItem.addMouseReleaseCBF(_changeStyle);
  };

  var _changeStyle =
  function(guiItem)
  {
    var gi = guiItem.getGuiItem();  

    var elem = gi.getDomNode();
    var state = gi.getState();
    var mouseState = gi.getMouseState();
    elem.className = _styles[state][mouseState];
  };

  var _styles = styles;
};
