
/*************************************************************************[info]
  FRAMEWORK:            eXtend
  DATA:                 04/02/2009
  COMPANY:              Onlime S.n.c.
 
  VERS:                 1.1
  LAST EDIT:            19/11/2009
  
  TODO:                 
    - funzione set style Inline Block cross da inserire
      http://code.google.com/p/doctype/wiki/ArticleInlineBlock
                            
  LIMITI:  
    - ...
*******************************************************************************/
(function() {
/*******************************************************************************
  [ESTENSIONE PROTOTIPI]  
*******************************************************************************/ 
/* 
  [Array.indexOf] - Recupero indice tramite elemento passato come argomento
  ---
  @obj        : OBJ       --oggetto da ricercare
  @start      : INT       --posizione di partenza
*/ 
if (!Array.indexOf) 
{
  Array.prototype.indexOf = function (obj, start) 
  {
    for (var i = (start || 0); i < this.length; i++) 
    {
      if (this[i] == obj){ return i; }
    }
    return -1;
  }
};

/* 
  [Array.each] - Esegue una funzione passata come argomento su ciascun elemento 
  dell'array
  ---
  @fn         : FUNCTION  --funzione da eseguire
  @scope      : OBJECT    --scope associato
*/
if (!Array.each) 
{
  Array.prototype.each = function ( fn, scope )
  {
    for(var j = 0, len = this.length; j < len; j++)
    {
	    fn.apply( scope || this[j], [ this[j], j, this ] );
	  }
  }
};

/* 
  [Array.remove] - By John Resig (MIT Licensed) 
  ---
  @from    : NUMBER   --from
  @to      : NUMBER   --to
*/
if (!Array.remove) 
{
  Array.prototype.remove = function(from, to) {
    var rest = this.slice((to || from) + 1 || this.length);
    this.length = from < 0 ? this.length + from : from;
    return this.push.apply(this, rest);
  };
};

/* 
  [Function.bind] - ...
  ---
  @object         : OBJECT  --scope
*/
Function.prototype.bind = function (object) 
{
   var method = this;
   var oldArguments = toArray(arguments).slice(1);
   return function () {
       var newArguments = toArray(arguments);
       return method.apply(object, oldArguments.concat(newArguments));
   };
};

/* 
  [Function.bindEventListener] - ...
  ---
  @object         : OBJECT  --scope
*/
Function.prototype.bindEventListener = function (object) 
{
   var method = this;
   var oldArguments = toArray(arguments).slice(1);
   return function (event) {
      if ( JEvent.eventStates[ oldArguments[0] ].status == 0 )
      {
        return method.apply(object, [event || window.event].concat(oldArguments));
      }
   };
};

/* 
  [Function.cascade] - ...
  ---
  @callbackFn         : FUNCTION  --callbackFn
*/
Function.prototype.cascade = function()
{ 
  var method = this;
  var oldArguments = toArray(arguments);

  return function() {
    var newArguments = toArray(arguments);
    
    var esito = method.apply( oldArguments[0], oldArguments.slice(2).concat(newArguments) );
    
    if ( (esito===true) && (oldArguments[1]) ) 
    {
      return oldArguments[1].apply( method );  
    }
  } 
};

/* NOT USED 
Object.prototype.Inherits = function( parent )
{
	if( arguments.length > 1 )
	{
		parent.apply( this, Array.prototype.slice.call( arguments, 1 ) );
	}
	else
	{
		parent.call( this );
	}
}
Function.prototype.Inherits = function( parent )
{
	this.prototype = new parent();
	this.prototype.constructor = this;
}
*/

/* 
  [Function.inherits] - ...
  ---
  @superclass         : OBJECT  --superclass
*/
Function.prototype.inherits = function(superclass) {
  var Tmp = function() {};
  Tmp.prototype = superclass.prototype;
  this.prototype = new Tmp();
  this.prototype.constructor = this;
} 
/*******************************************************************************
  [END ESTENSIONE PROTOTIPI]  
*******************************************************************************/
/*******************************************************************************
  [OVERLOADIND DEGLI OGGETTI EXTEND, EVENT, AJAX]  
*******************************************************************************/
/* 
  [$] - ...
  ---
  @selector         : [string,object]  --selector
*/
$ = function( selector ) 
{ 
  var obj = null;
  
  if ( typeOf(selector) == 'string' )
  {  
    obj  = document.getElementById( selector );
  }
  else if ( typeOf(selector) == 'object' )
  {
    obj = selector;
  }
  else
  {
    return null;
  }
  
  if ( !obj ) return null;
  
  if( obj.fn )
  {
    return obj; // recupero
  }
  else
  {
    // Attach delle funzioni estese
    obj.fn = new eXtend( obj ); // istanzio
    return obj;
  } 
};

/* 
  [$$] - ...
  ---
  @selector         : [string,array]  --selector
*/
window.$$ = function( selector ) 
{
  var array_ret = [];
  
  if ( typeOf(selector) == 'string' )
  {  
    var splitted = selector.split(' ');
    
    for (var i=0;i<splitted.length;i++)
    {
      if ( splitted[i].charAt(0) == '#')
      {
        // element by id
        var obj  = document.getElementById( splitted[i].substring(1) );
        if ( obj ) array_ret.push( obj );
      }
      else if( splitted[i].charAt(0) == '.' )
      {
        // element by classname
        var arr_obj = getElementsByClass( splitted[i].replace('.','') );
        for (var j=0;j<arr_obj.length;j++){ array_ret.push( arr_obj[j] ); }
      }
    }
  }
  else if ( typeOf(selector) == 'array' )
  {
    array_ret = selector;
  }
  
  if ( array_ret.length == 0 ) return null;
   
  array_ret.fn = new Group ( array_ret );
  return array_ret; 
};
/*******************************************************************************
  [END OVERLOADIND DEGLI OGGETTI EXTEND, EVENT, AJAX]  
*******************************************************************************/

/*******************************************************************************
  [EXTEND OBJECT]  
*******************************************************************************/
eXtend = function( obj )
{
  if (!obj) return;
  
  this.domElm  = null;
	this.elm_id  = null;
  this.lock    = null;
  
  // all'istanziazione bindo il "package" UI e data
  this.UI   = eXtend.UI.bind(this)();
  this.data = eXtend.data.bind(this)();
  
  this.data.init( obj );
};

eXtend.prototype.isChildOf = function( parent ) 
{
  return Utility.isChildOf ( this.domElm, parent )
};

eXtend.prototype.css = function (parameters)
{
	obj = this.domElm;
	
	if ( typeOf(parameters) == "object" ){  	
  	for (var param in parameters) 
    {
      obj.style[param] = parameters[param];
    }
  }
  else if ( typeOf(parameters) == "string" )
  {
    if (obj.currentStyle) return obj.currentStyle[parameters];
	   else if (window.getComputedStyle)
		  return document.defaultView.getComputedStyle(obj,null).getPropertyValue(parameters);
  }
  else if ( typeOf(parameters) == "array" )
  {
    var arr_ret = {};
    for (var i=0;i<parameters.length;i++)
    {
      if (obj.currentStyle) arr_ret[parameters[i]] = obj.currentStyle[parameters[i]];
	     else if (window.getComputedStyle)
		    arr_ret[parameters[i]] = document.defaultView.getComputedStyle(obj,null).getPropertyValue(parameters[i]);         
    }
    return arr_ret;
  }
};

eXtend.prototype.manageClassName = function (a,c1,c2)
{
  return Utility.manageClassName(a,this.domElm,c1,c2);
}

eXtend.UI = function()
{
  var eXobj = this;
  
  var pk = {
      setOpacity      : function( level ){
          return GE.setOpacity.apply( eXobj, [level] );
        },
      getOpacity      : function( level ){
          return GE.getOpacity.apply( eXobj );
        },     
      fadeOut         : function ( parameters, cbFn ){
          return GE.fadeOut.apply( eXobj, [parameters,cbFn] );
        },
      fadeIn          : function ( parameters, cbFn ){
          return GE.fadeIn.apply( eXobj, [parameters,cbFn] );
        },
      open            : function ( parameters, cbFn ){
          return GE.open.apply( eXobj, [parameters,cbFn] );
        },
      close           : function ( parameters, cbFn ){
          return GE.close.apply( eXobj, [parameters,cbFn] );
        },
      fadeColor       : function ( parameters, cbFn ){
          return GE.fadeColor.apply( eXobj, [parameters,cbFn] );
        },
      slide           : function ( parameters,cbFn ){
          return GE.slide.apply( eXobj, [parameters,cbFn] );
        },
      morphing        : function ( parameters, cbFn ){
          return GE.morphing.apply( eXobj, [parameters,cbFn] );
        },
      slideBackground : function ( parameters, cbFn ){
          return GE.slideBackground.apply( eXobj, [parameters,cbFn] );
        },  
      // -- Composite --  
      slideAndMorphing  : function ( parametersSlide, parametersMorphing, cbFn ){
          return GE.slideAndMorphing.apply( eXobj, [parametersSlide,parametersMorphing,cbFn] );
        },
      reduceAndClose  :  function ( parametersMorphing, parametersClose, cbFn  ){
          return GE.reduceAndClose.apply( eXobj, [parametersMorphing,parametersClose,cbFn] );
        },
      fadeOutAndClose  :  function ( parametersFadeOut, parametersClose, cbFn  ){
          return GE.fadeOutAndClose.apply( eXobj, [parametersFadeOut,parametersClose,cbFn] );
        },
      openAndFadeIn  :  function ( parametersOpen, parametersFadeIn, cbFn ){
          return GE.openAndFadeIn.apply( eXobj, [parametersOpen,parametersFadeIn,cbFn] );
        },
      reduceFadeOutAndClose  :  function ( parameters, cbFn ){
          return GE.reduceFadeOutAndClose.apply( eXobj, [parameters,cbFn] );
        }  
    };
    
  return pk; 
};

eXtend.data = function()
{
  var eXobj = this;
  
  var pk = {
    init : function( obj )
      { 
        eXobj.domElm  = obj;
      	eXobj.elm_id  = obj.id;
        eXobj.lock    = false;
        
        // Da controllare
        if ( eXobj.css('display') == 'none' )      eXobj.data.effects.display = false;
        if ( eXobj.css('visibility') == 'hidden' ) eXobj.data.effects.visible = false;
        
        eXobj.data.effects.curBgColor = ( eXobj.css('backgroundColor') || '#FFFFFF' );  //  Da rendere funzionante (RGB esa da trasformare)
        eXobj.data.effects.curBdColor = ( eXobj.css('borderColor')     || '#FFFFFF' );  //  Da rendere funzionante (RGB esa da trasformare)
        eXobj.data.effects.oHeight    = ( eXobj.domElm.offsetHeight || parseFloat(eXobj.css('height')) );
        eXobj.data.effects.oWidth     = ( eXobj.domElm.offsetWidth  || parseFloat(eXobj.css('width'))  );
      },
      
    // Ricontrollare uso e validità del pacchetto  
    effects : {
        "visible"       : true,
        "display"       : true,
        "curBgColor"    : "#FFFFFF",    // Background Color
        "curBdColor"    : "#FFFFFF",    // Border Color
        "curFtColor"    : "#000000",    // Font Color
        "oHeight"       : null,         // Original Height
        "oWidth"        : null          // Original Width
      } 
    };
  
  return pk;
};
/*******************************************************************************
  [END EXTEND OBJECT]  
*******************************************************************************/

/*******************************************************************************
  [Group OBJECT]  
*******************************************************************************/
Group = function ( arr_obj )
{
  this.arr_elm = null;
  
  this.init( arr_obj );
  this.UI = this.UI.bind(this)();  
} 
 
Group.prototype.init = function( arr_obj )
{
  this.arr_elm = [];
  
  var fn = function (obj){ this.arr_elm.push( $( obj ) ) };
  arr_obj.each( fn, this );
}

Group.prototype.UI = function()
{
  var groupObj = this;
  
  var pk = { 
      fadeOut     : function ( parameters ){
          var fn = function (){ this.fn.UI.fadeOut( parameters ) };
          return groupObj.arr_elm.each( fn );
        },
      fadeIn      : function ( parameters ){
          var fn = function (){ this.fn.UI.fadeIn( parameters ) };
          return groupObj.arr_elm.each( fn );
        },  
      open        : function ( parameters ){
          var fn = function (){ this.fn.UI.open( parameters ) };
          return groupObj.arr_elm.each( fn );
        }, 
      close       : function ( parameters ){
          var fn = function (){ this.fn.UI.close( parameters ) };
          return groupObj.arr_elm.each( fn );
        },  
      fadeColor   : function ( parameters ){
          var fn = function (){ this.fn.UI.fadeColor( parameters ) };
          return groupObj.arr_elm.each( fn );
        },  
      fadeOutAndClose  :  function ( parametersFadeOut, parametersClose ){
          var fn = function (){ this.fn.UI.fadeOutAndClose( parametersFadeOut, parametersClose ) };
          return groupObj.arr_elm.each( fn );
        },
      openAndFadeIn  :  function ( parametersOpen, parametersFadeIn ){
          var fn = function (){ this.fn.UI.openAndFadeIn( parametersOpen, parametersFadeIn ) };
          return groupObj.arr_elm.each( fn );
        },
      openOnly : function ( elm ){
          var fn = function ()
          {
            if ( typeOf(elm) == 'string' )
            {
              if ( this.id != elm ) this.fn.UI.close();
              else this.fn.UI.open();
            }
            else
            {
              if ( this !== elm ) this.fn.UI.close();
              else this.fn.UI.open();
            }
          };
          return groupObj.arr_elm.each( fn );
        } 
    };
  
  return pk;
}

Group.prototype.addEventListener = function(evType, funct, useCapture, opt)
{
  var arrListener = [];
  
  var fn = function (){ arrListener.push( $E.add( this,evType, funct, useCapture, opt ) ); };
  this.arr_elm.each( fn );
  
  return arrListener;
}
/*******************************************************************************
  [END Group OBJECT]  
*******************************************************************************/


/*******************************************************************************
  [GE]  
*******************************************************************************/
GE = {};

/* [setOpacity]
    @opacity  : opacitá
    
   Note : per setOpacity su elementi contenenti font impostare il colore di 
   sfondo del background. 
*/ 
GE.setOpacity = function ( opacity )
{
  opacity=(opacity==100) ? 99.999 : opacity;
  
  this.css ({
    // IE/Win
    "filter": "alpha(opacity:"+opacity+")",
    //filter: "progid:DXImageTransform.Microsoft.Alpha(opacity="+opacity+")",
    // Safari<1.2, Konqueror
    "KHTMLOpacity" : opacity/100,
    // Older Mozilla and Firefox
    "MozOpacity" : opacity/100,
    // Safari 1.2, newer Firefox and Mozilla, CSS3
    "opacity" : opacity/100
  });
};

/** [getOpacity] 
*/ 
GE.getOpacity = function ()
{ 
  var x = this.css( ["KHTMLOpacity","MozOpacity","opacity","filter"] );
  
  var opacity     = null;
  var parsestring = null;
  var reg         = /[\d.]+/g;
  
  for ( i in x ) 
  { 
    parsestring = reg.exec( x[i] );
    
    if( parsestring )
    { 
      if( i != "filter" ) opacity = parsestring * 100;
      else opacity = parsestring;
    }
  }
  
  opacity = ( (opacity==null) || (opacity==undefined) ) ? ( 100 ) : ( opacity ); 
  return opacity;
};

/* [fadeOut]
@parameters v    : 
@parameters a    : 
@parameters o    : 
@parameters lim_opacity : limite opacitá
@cbFn : funzione di callback
*/         
GE.fadeOut  = function ( parameters, cbFn )
{ 
  if ( this.lock ) return;
  
  if (!parameters) parameters = {};
  var v = (parameters['v']) || 0;
  var a = (parameters['a']) || 0.15;
  var x = (parameters['lim_opacity']) || 0;
  var y = (parameters['o'] == undefined ) ? GE.getOpacity.apply( this ) : parameters['o'];
  
  cbFn = cbFn || null;
  
  // Call executeSlide
  GE.executeFadeOut.apply( this, [ v, a, 0, x, y, cbFn ] );
  
};

GE.executeFadeOut = function ( v, a, t, x, y, cbFn )
{ 
  var o = y - ( v * t ) - ( 1/2 * a * (t * t) );

  if ( o < x ) o = x;
  
  this.UI.setOpacity( o );
  
  if ( o <= x ) return true;

  t++;
  
  if( cbFn )
  {
    var fn = GE.executeFadeOut.cascade( this, cbFn, v, a, t, x, y, cbFn );
  }
  else
  {
    var fn = GE.executeFadeOut.bind ( this, v, a, t, x, y, cbFn );
  }
  
  window.setTimeout( fn, 20 );
  return false;
};

/* [fadeIn]
@parameters v    : 
@parameters a    : 
@parameters o    : 
@parameters lim_opacity : limite opacitá
@cbFn : funzione di callback
*/         
GE.fadeIn  = function ( parameters, cbFn )
{ 
  if ( this.lock ) return;
  
  if (!parameters) parameters = {};
  var v = (parameters['v']) || 0;
  var a = (parameters['a']) || 0.15;
  var x = (parameters['lim_opacity']) || 100;
  var y = (parameters['o'] == undefined ) ? GE.getOpacity.apply( this ) : parameters['o'];
  
  cbFn = cbFn || null;
  
  // Call executeSlide
  GE.executeFadeIn.apply( this, [ v, a, 0, x, y, cbFn ] );
  
};

GE.executeFadeIn = function ( v, a, t, x, y, cbFn )
{ 
  var o = y + ( v * t ) + ( 1/2 * a * (t * t) );

  if ( o > x ) o = x;
  
  this.UI.setOpacity( o );
  
  if ( o >= x ) return true;

  t++;
  
  if( cbFn )
  {
    var fn = GE.executeFadeIn.cascade( this, cbFn, v, a, t, x, y, cbFn );
  }
  else
  {
    var fn = GE.executeFadeIn.bind ( this, v, a, t, x, y, cbFn );
  }
  
  window.setTimeout( fn, 20 );
  return false;
};

/* [close]
@parameters displayMode : displayMode
@cbFn : funzione di callback
*/
GE.close = function ( parameters, cbFn )
{   
  if ( this.data.effects.display )
  {
    parameters = (parameters) ? (parameters) : ({});
    
    this.css({ "display" : "none" });
    this.data.effects.display = false;
    
    if ( cbFn ){ cbFn(); }
  }

  return true;
};

/* [open]
@parameters displayMode : displayMode
@cbFn : funzione di callback
*/
GE.open = function ( parameters, cbFn )
{ 
  if ( !this.data.effects.display )
  {
    parameters = (parameters) ? (parameters) : ({});
    var displayMode = (parameters["displayMode"]) || "block";
    
    this.css({ "display" : displayMode });
    this.data.effects.display = true;
    
    if ( cbFn ){ cbFn(); }
  }  
  return true;
};


/* [fadeColor]
@parameters v    : velocitá
@parameters a    : accuratezza
@parameters t    : on css element ['background'/'border'/'font']
@parameters fromColor : da colore
@parameters toColor   : a colore
@cbFn : funzione di callback
*/ 
GE.fadeColor = function ( parameters, cbFn )
{ 
  if ( this.lock ) return;
  
  if (!parameters) parameters = {};
  var v = (parameters['v'])  || 60;
  var a = (parameters['a'])  || 20;
  var t = (parameters['on']) || 'background';
  
  if ( t=='background' )
  {
    var fromRgbColor = Utility.RGB( (parameters['fromColor']) || (this.data.effects.curBgColor) );
    var toRgbColor   = Utility.RGB( (parameters['toColor'])   || (this.data.effects.curBgColor) );
  }
  else if ( t=='border' )
  {
    var fromRgbColor = Utility.RGB( (parameters['fromColor']) || (this.data.effects.curBdColor) );
    var toRgbColor   = Utility.RGB( (parameters['toColor'])   || (this.data.effects.curBdColor) );
  }
  else if ( t=='font' )
  {
    var fromRgbColor = Utility.RGB( (parameters['fromColor']) || (this.data.effects.curFtColor) );
    var toRgbColor   = Utility.RGB( (parameters['toColor'])   || (this.data.effects.curFtColor) );
  }
  
  var cresciteRgb = [];
  for (i=0;i<3;i++)
  {
    cresciteRgb[i] = ( fromRgbColor[i] <= toRgbColor[i] ) ? true : false;
    
    if( fromRgbColor[i] < toRgbColor[i] ){ cresciteRgb[i] = 1 }
    else if( fromRgbColor[i] > toRgbColor[i] ){ cresciteRgb[i] = 2 }
    else{ cresciteRgb[i] = 3 }    
  }
  
  // da verificare
  cbFn = cbFn || null;
    
  // Call computing_fade
  GE.executeFadeColor.apply( this, [ fromRgbColor, toRgbColor, cresciteRgb, a, v, t, cbFn ] );   
};

/* [executeFadeColor]
@currentRgbColor : array valori rgb correnti
@toRgbColor      : array valori rgb finali
@cresciteRgb     : array crescite rgb
@accuracy        : accuratezza
@time            : velocitá
@on              : css element ['background'/'border'/'font']
*/
GE.executeFadeColor = function ( currentRgbColor, toRgbColor, cresciteRgb, accuracy, time, on, cbFn )
{ 
  // exit condition
  if ( 
    (currentRgbColor[0] == toRgbColor[0]) &&
    (currentRgbColor[1] == toRgbColor[1]) &&
    (currentRgbColor[2] == toRgbColor[2])
  )
  {
    return true; 
  }
  
  for (i=0;i<3;i++)
  {
    if ( (cresciteRgb[i] == 1) && ( (currentRgbColor[i]+accuracy) < toRgbColor[i]) )
    {
      currentRgbColor[i] += accuracy;
    }
    else if ( (cresciteRgb[i] == 2) && ( (currentRgbColor[i]-accuracy) > toRgbColor[i]) )
    {
      currentRgbColor[i] -= accuracy;
    }
    else
    {
      cresciteRgb[i] = 3;
      currentRgbColor[i] = toRgbColor[i];
    }
  }
  
  if ( on=='background' )
  {     
    this.css({ 'backgroundColor': Utility.HEX( currentRgbColor ) });
    this.data.effects.curBgColor = Utility.HEX( currentRgbColor );
  }
  else if ( on=='border' )
  { 
    this.css({ 'borderColor': Utility.HEX( currentRgbColor ) });
    this.data.effects.curBdColor = Utility.HEX( currentRgbColor );
  }
  else if ( on=='font' )
  {
    this.css({ 'color': Utility.HEX( currentRgbColor ) });
    this.data.effects.curFtColor = Utility.HEX( currentRgbColor );
  }
  
  if( cbFn )
  {
    var fn = GE.executeFadeColor.cascade( this, cbFn, currentRgbColor,toRgbColor,cresciteRgb,accuracy,time,on,cbFn ); 
  }
  else
  {
    var fn = GE.executeFadeColor.bind( this, currentRgbColor,toRgbColor,cresciteRgb,accuracy,time,on, null );
  }
  
  window.setTimeout(fn, time);
  
  return false;
};

/* [slide]
@parameters ... 
*/            
GE.slide  = function ( parameters, cbFn )
{ 
  if ( this.lock ) return;
  if (!parameters) parameters = {};
  
  var v   = (parameters["v"]) || 0;
  var a   = (parameters["a"]) || 0.5;
  var x   = (parameters["x"]) || 0;
  var y   = (parameters["y"]) || 0;
  var z   = (parameters["z"]) || "auto";
  var p   = (parameters["p"]) || "relative";
  var x0  = ( is_numeric(parameters['x0']) ) ? ( parameters['x0'] ) : ( parseFloat( this.css('left') ) || 0  );
  var y0  = ( is_numeric(parameters['y0']) ) ? ( parameters['y0'] ) : ( parseFloat( this.css('top') ) || 0 );
  var x1  = ( is_numeric(parameters['x1']) ) ? ( parameters['x1'] ) : ( null );
  var y1  = ( is_numeric(parameters['y1']) ) ? ( parameters['y1'] ) : ( null );
  
  x  = ( x1 ) ? ( x1-x0 ) : ( x );
  y  = ( y1 ) ? ( y1-y0 ) : ( y );
  
  var maxX = Math.abs( (x) );
  var maxY = Math.abs( (y) );
  
  var rate = ( (maxY==0) || (maxX==0) ) ? ( 1 ):( maxY/maxX );
  
  var aX = a;
  var aY = a*rate;
  
  this.css({
    "position" : String(p),
    "zIndex" : String(z) & "" // forcing casting for solve ie problem
  });

  var arrFromCoord = [x0,y0];

  cbFn = cbFn || null;

  var arrOffset = [x,y];
  
  // Call executeSlide
  GE.executeSlide.apply( this, [ arrFromCoord, arrOffset, v, 0, aX, aY ,cbFn ] );
};

GE.executeSlide = function ( arrFromCoord, arrOffset, v, t, aX, aY, cbFn )
{ 
  var signX = ( arrOffset[0] >= 0 ) ? ( +1 ) : ( -1 );
  var signY = ( arrOffset[1] >= 0 ) ? ( +1 ) : ( -1 );
  
  var x = arrFromCoord[0] + signX * ( ( v * t ) + ( 1/2 * aX * (t * t) ) );
  var y = arrFromCoord[1] + signY * ( ( v * t ) + ( 1/2 * aY * (t * t) ) );

  if ( Math.abs(x - arrFromCoord[0]) > Math.abs(arrOffset[0]) ) x = arrFromCoord[0] + arrOffset[0];
  if ( Math.abs(y - arrFromCoord[1]) > Math.abs(arrOffset[1]) ) y = arrFromCoord[1] + arrOffset[1];

  this.css({
    "left"  : x+"px",
    "top"   : y+"px"
  });
  
  if (  
    (Math.abs(x - arrFromCoord[0]) >= Math.abs(arrOffset[0])) && 
    (Math.abs(y - arrFromCoord[1]) >= Math.abs(arrOffset[1])) 
  ) return true;

  t++;
  
  if( cbFn )
  {
    var fn = GE.executeSlide.cascade( this, cbFn, arrFromCoord, arrOffset, v, t, aX, aY, cbFn );
  }
  else
  {
    var fn = GE.executeSlide.bind( this, arrFromCoord, arrOffset, v, t, aX, aY, cbFn );
  }
  
  window.setTimeout( fn, 20 );
  return false;
}; 

GE.morphing = function ( parameters, cbFn )
{ 
  if (!parameters) parameters = {};
  
  var v   = (parameters['v']) || 0;
  var a   = (parameters['a']) || 0.5;
  var x   = (parameters['x']) || 0;
  var y   = (parameters['y']) || 0;
  var x0  = ( is_numeric(parameters['x0']) ) ? ( parameters['x0'] ) : ( this.domElm.offsetWidth || parseFloat(this.css('width')) );
  var y0  = ( is_numeric(parameters['y0']) ) ? ( parameters['y0'] ) : ( this.domElm.offsetHeight || parseFloat(this.css('height')) );
  var x1  = ( is_numeric(parameters['x1']) ) ? ( parameters['x1'] ) : ( null );
  var y1  = ( is_numeric(parameters['y1']) ) ? ( parameters['y1'] ) : ( null );
  
  x  = ( x1 ) ? ( x1-x0 ) : ( x );
  y  = ( y1 ) ? ( y1-y0 ) : ( y );
  
  var maxX = Math.abs( (x) );
  var maxY = Math.abs( (y) ); 
  
  var rate = ( (maxY==0) || (maxX==0) ) ? ( 1 ):( maxY/maxX );
  
  var aX = a;
  var aY = a*rate;
  
  var arrFromCoord  = [x0,y0];
  var arrOffset     = [x,y];
  
  cbFn = cbFn || null;
  
  // Call executeMorphing
  GE.executeMorphing.apply( this , [ arrFromCoord, arrOffset, v, 0, aX, aY, cbFn ] );
}
    
GE.executeMorphing = function ( arrFromCoord, arrOffset, v, t, aX, aY, cbFn )
{ 
  var signX = ( arrOffset[0] >= 0 ) ? ( +1 ) : ( -1 );
  var signY = ( arrOffset[1] >= 0 ) ? ( +1 ) : ( -1 );
  
  var x = arrFromCoord[0] + signX * ( ( v * t ) + ( 1/2 * aX * (t * t) ) );
  var y = arrFromCoord[1] + signY * ( ( v * t ) + ( 1/2 * aY * (t * t) ) );

  if ( Math.abs(x - arrFromCoord[0]) > Math.abs(arrOffset[0]) ) x = arrFromCoord[0] + arrOffset[0];
  if ( Math.abs(y - arrFromCoord[1]) > Math.abs(arrOffset[1]) ) y = arrFromCoord[1] + arrOffset[1];

  this.css({
    "width"  : x+"px",
    "height" : y+"px"
  });
  
  if (  
    (Math.abs(x - arrFromCoord[0]) >= Math.abs(arrOffset[0])) && 
    (Math.abs(y - arrFromCoord[1]) >= Math.abs(arrOffset[1])) 
  ) return true;

  t++;
  
  if( cbFn )
  {
    var fn = GE.executeMorphing.cascade( this, cbFn, arrFromCoord, arrOffset, v, t, aX, aY, cbFn );
  }
  else
  {
    var fn = GE.executeMorphing.bind( this, arrFromCoord, arrOffset, v, t, aX, aY, cbFn );
  }
  
  window.setTimeout( fn, 20 );
  return false;
};

/* [slideBackground]
@parameters ...
*/            
GE.slideBackground  = function ( parameters, cbFn )
{ 
  if ( this.lock ) return;
  if (!parameters) parameters = {};
  
  var v   = (parameters["v"]) || 0;
  var a   = (parameters["a"]) || 0.5;
  var x   = (parameters["x"]) || 0;
  var y   = (parameters["y"]) || 0;
  
  // ! Verificare che nn vi siano errori nel recupero background x e y position
  var arrPos = this.domElm.style.backgroundPosition.split(" ");
  var x0  = ( is_numeric(parameters['x0']) ) ? ( parameters['x0'] ) : ( parseFloat( arrPos[0] ) || 0 );
  var y0  = ( is_numeric(parameters['y0']) ) ? ( parameters['y0'] ) : ( parseFloat( arrPos[1] ) || 0 );
  var x1  = ( is_numeric(parameters['x1']) ) ? ( parameters['x1'] ) : ( null );
  var y1  = ( is_numeric(parameters['y1']) ) ? ( parameters['y1'] ) : ( null );
  
  x  = ( x1 ) ? ( x1-x0 ) : ( x );
  y  = ( y1 ) ? ( y1-y0 ) : ( y );
  
  var maxX = Math.abs( (x) );
  var maxY = Math.abs( (y) ); 
  
  var rate = ( (maxY==0) || (maxX==0) ) ? ( 1 ):( maxY/maxX );
  
  var aX = a;
  var aY = a*rate;
  
  var arrFromCoord = [x0,y0]; 

  cbFn = cbFn || null;

  var arrOffset = [ x, y ];
  
  // Call executeSlide
  GE.executeSlideBackground.apply( this, [ arrFromCoord, arrOffset, v, 0, aX, aY ,cbFn ] );
};

GE.executeSlideBackground = function ( arrFromCoord, arrOffset, v, t, aX, aY, cbFn )
{ 
  var signX = ( arrOffset[0] >= 0 ) ? ( +1 ) : ( -1 );
  var signY = ( arrOffset[1] >= 0 ) ? ( +1 ) : ( -1 );
  
  var x = arrFromCoord[0] + signX * ( ( v * t ) + ( 1/2 * aX * (t * t) ) );
  var y = arrFromCoord[1] + signY * ( ( v * t ) + ( 1/2 * aY * (t * t) ) );

  if ( Math.abs(x - arrFromCoord[0]) > Math.abs(arrOffset[0]) ) x = arrFromCoord[0] + arrOffset[0];
  if ( Math.abs(y - arrFromCoord[1]) > Math.abs(arrOffset[1]) ) y = arrFromCoord[1] + arrOffset[1];

  this.css({
    "backgroundPosition" : x+"px " + y+"px"
  });
  
  if (  
    (Math.abs(x - arrFromCoord[0]) >= Math.abs(arrOffset[0])) && 
    (Math.abs(y - arrFromCoord[1]) >= Math.abs(arrOffset[1])) 
  ) return true;

  t++;
  
  if( cbFn )
  {
    var fn = GE.executeSlideBackground.cascade( this, cbFn, arrFromCoord, arrOffset, v, t, aX, aY, cbFn );
  }
  else
  {
    var fn = GE.executeSlideBackground.bind( this, arrFromCoord, arrOffset, v, t, aX, aY, cbFn );
  }
  
  window.setTimeout( fn, 20 );
  return false;
};
          
GE.slideAndMorphing  = function ( parametersSlide, parametersMorphing, cbFn )
{ 
  if ( this.lock ) return;
  
  parametersSlide     = (!parametersSlide)    ? ( {} ) : ( parametersSlide );
  parametersMorphing  = (!parametersMorphing) ? ( {} ) : ( parametersMorphing );
  
  var cbSlide    = parametersSlide["cbFn"] || null;
  var cbMorphing = parametersMorphing["cbFn"] || null;
  
  var arEsiti = {
    "0" : { "stato":false,"cbFn":cbSlide },
    "1" : { "stato":false,"cbFn":cbMorphing }
  };
  
  if ( cbFn ) arEsiti.cbFn = cbFn;
  
  parametersSlide["cbFn"] = sync.bind(arEsiti,0);
  this.UI.slide( parametersSlide, parametersSlide["cbFn"] );
  
  parametersMorphing["cbFn"] = sync.bind(arEsiti,1);
  this.UI.morphing( parametersMorphing, parametersMorphing["cbFn"] );
}


GE.reduceAndClose = function ( parametersMorphing, parametersClose, cbFn )
{
  if ( this.lock ) return;
  
  if ( this.data.effects.display )
  { 
    parametersMorphing  = (!parametersMorphing) ? ( {} ) : ( parametersMorphing );
    parametersClose     = (!parametersClose)    ? ( null ) : ( parametersClose );
  
    parametersMorphing["newWidth"]  = 1;
    parametersMorphing["newHeight"] = 1;
    
    cbFn = cbFn || null;
    
    var fnCbClose = this.UI.close.cascade( this, cbFn, parametersClose );
    this.UI.morphing( parametersMorphing, fnCbClose );
  }
};

/* [fadeOutAndClose]
@parametersFadeOut : fadeOutParameters
@parametersClose   : closeParameters
@cbFn : funzione di callback
*/ 
GE.fadeOutAndClose = function ( parametersFadeOut, parametersClose, cbFn )
{
  if ( this.lock ) return;
  
  if ( this.data.effects.display )
  {
    parametersClose   = ( !parametersClose ) ? ( {} ) : ( parametersClose );
    parametersFadeOut = ( !parametersFadeOut ) ? ( {} ) : ( parametersFadeOut );
    
    cbFn = cbFn || null;
    
    var fnCbClose = this.UI.close.cascade( this, cbFn, parametersClose );
    this.UI.fadeOut( parametersFadeOut, fnCbClose );
  }  
};

/* [openAndFadeIn]
@parametersOpen   : parametersOpen
@parametersFadeIn : parametersFadeIn
@cbFn : funzione di callback
*/
GE.openAndFadeIn = function( parametersOpen, parametersFadeIn, cbFn )
{
  if ( this.lock ) return;
  
  if ( !this.data.effects.display )
  {
    parametersOpen     = ( !parametersOpen ) ? ( {} ) : ( parametersOpen );
    parametersFadeIn   = ( !parametersFadeIn ) ? ( {} ) : ( parametersFadeIn );
    
    cbFn = cbFn || null;
    
    this.UI.setOpacity(0);  // ? lo lasciamo ?
    
    var fnCbFadeIn = GE.fadeIn.bind( this, parametersFadeIn, cbFn );
    this.UI.open( parametersOpen, fnCbFadeIn );
  }
};

/* [reduceFadeOutAndClose]
@parameters   : parameters
@cbFn : funzione di callback
*/
GE.reduceFadeOutAndClose = function ( parameters, cbFn )
{
  if ( this.lock ) return;
  
  if ( this.data.effects.display )
  {
    parameters = (parameters) ? (parameters) : ( {} );
    var v = parameters["v"] || 10;
    var a = parameters["a"] || 2;
    
    var parametersMorphing = { "newWidth":1,"newHeight":1,"v":v };
    var parametersFadeOut = { "v":v };
    
    var x = parseFloat( this.css ("width") );
    var y = parseFloat( this.css ("height") );
    
    var max = ( x > y ) ? ( x ) : ( y );
    var rate = 100 / max; 
    
    parametersMorphing["a"] = a;
    parametersFadeOut["a"]  = a*rate;
    
    cbFn = cbFn || null;
    
    // !Occorre calcolare il rapporto giusto tra fadeOut e morphing(reduce)
    // in base a dimensioni height e width obj, velocità, accuracy.
    
    cbFn = cbFn || null;
    var fnCbClose = this.UI.close.cascade( this, cbFn, null, null );
    
    this.UI.fadeOut( parametersFadeOut, null ); 
    this.UI.morphing( parametersMorphing, fnCbClose );
  }  
};
/*******************************************************************************
  [END GE]  
*******************************************************************************/
/*******************************************************************************
  [UTILITY]  
*******************************************************************************/
Utility = {};

// Funzione Cross per recuperare gli oggetti appartenenti ad una data classe 
// dato il nodo di partenza e il tipo di nodo
Utility.getElementsByClassName = function (oElm, strTagName, strClassName)
{
	var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
	
	var arrReturnElements = new Array();
	
  strClassName = strClassName.replace(/\-/g, "\\-");
  var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
	var oElement;
	
  for(var i=0; i<arrElements.length; i++)
  {
		oElement = arrElements[i];
		if( oRegExp.test(oElement.className) )
    {
			arrReturnElements.push(oElement);
		}
	}
	
	return (arrReturnElements)
};

// Funzione Cross per recuperare tutti gli oggetti appartenenti ad una data classe
Utility.getElementsByClass = function (strClassName)
{
  return Utility.getElementsByClassName(document, "*", strClassName);
};

// typeof ottimizzata (torna direttamente anche tipo array e null) 
Utility.typeOf = function (value) 
{
  var s = typeof value;
  if( s === 'object' )
  {
    if( value )
    {
      if( (typeof value.length === 'number') &&
          (value.propertyIsEnumerable) && // fix errore generato in ie per elm DOM
          !(value.propertyIsEnumerable('length')) &&
          (typeof value.splice === 'function')
        ){ s = 'array'; }
    } 
    else{ s = 'null'; }
  }
  return s;
};

/* 
  [toArray] - Trasforma un pseudo array in array
  ---
*/
Utility.toArray = function ( pseudoArray ) 
{
   var result = [];
   for (var i = 0; i < pseudoArray.length; i++) result.push(pseudoArray[i]);
   return result;
};

/* 
  [sync] - ...
  ---
*/
Utility.sync = function ( idx )
{
  this[idx]["stato"] = true;
  if ( this[idx]["cbFn"] ) this[idx]["cbFn"]();
  
  for ( var i in this )
  {
    if ( this[i]["stato"] === false ) return;
  }
  
  if ( this.cbFn ) this.cbFn();
};

// retriveRcFromXml  
Utility.retriveRcFromXml =  function ( rcName, responseXml )
{
  var ans_ret = [];
  var rc_ans = null;
  var ans = responseXml.getElementsByTagName("recordset");

  for(i=0;i<ans.length;i++)
  { 
    if ( ans[i].getAttribute("name") == rcName )
    {
      rc_ans = ans[i];
      break;
    }
  }
  
  if (!rc_ans) return null;
  
  ans = rc_ans.getElementsByTagName("record");
  
  for(i=0;i<ans.length;i++)
  {
    ans_ret[i] = new Array();
    var campi = ans[i].getElementsByTagName("campo");
    
    for(k=0;k<campi.length;k++)
    {
      var chiave = campi[k].getAttribute("chiave");
      var valore = campi[k].childNodes[0].nodeValue;
      ans_ret[i][chiave] = valore;
    }
  }
  
  return ans_ret;
};

Utility.parseStrToJson = function ( str )
{ 
  return eval("("+str+")");
};

Utility.parseFileToXml = function ( file )
{
  var xmlDom = Utility.createXmlDom();
  if ( xmlDom )
  {
    try
    {
      xmlDom.async = false;
      xmlDom.load( file );
      return xmlDom;
    }
    catch(e)
    {
      return null;
    }
  }
  return null;
};

Utility.createXmlDom = function()
{
  var xmlDomObj;
  //preserveWhiteSpace = preserveWhiteSpace || true;
  
  try
  {
    xmlDomObj = new ActiveXObject("Microsoft.XMLDOM");
  }
  catch(e)
  {
    try
    {
      xmlDomObj = document.implementation.createDocument("","",null);
    }
    catch(e)
    {
      return null;
    }
  }
  
  xmlDomObj.preserveWhiteSpace = true;
  return xmlDomObj;
};

Utility.parseStrToXml = function ( str )
{
  try
  {
    var xmlDom = Utility.createXmlDom();
    xmlDom.async = "false";
    xmlDom.loadXML( str );
    return xmlDom;
  }
  catch(e)
  {
    try
    {
      var parser = new DOMParser();
      xmlDom = parser.parseFromString( str,"text/xml" );
      return xmlDom ;
    }
    catch(e)
    {
      return null;
    }
  }
};

Utility.xsltTransform = function( xmlDom, xsltDom, target )
{
  if ( (xmlDom == null) || (xsltDom == null) ) return null;

  try
  {
    var transform = xmlDom.transformNode( xsltDom );
    target.innerHTML = transform;
  }
  catch(e)
  {
    try
    {
      var xsltProcessor = new XSLTProcessor();
      xsltProcessor.importStylesheet( xsltDom );
      var transform = xsltProcessor.transformToFragment( xmlDom, document );
      target.appendChild( transform );
    }
    catch(e)
    {
      return null;
    }
  }
  
  return true;
}


Utility.visitDomTree = function( currNode, fn, level )
{
  if ( level && (level<0) ) return;
  
  fn( currNode );
  // Controllo che il nodo abbia figli
  if(currNode.childNodes.length > 0)
  {
    // Per ogni figlio del nodo corrente
    for(var i=0; currNode.childNodes.item(i); i++)
    {
      // Chiamo ricorsivamente la funzione
      Utility.visitDomTree( currNode.childNodes.item(i), fn, (level-1) );
    }
  }
};

/**
* setUnselectable
* Da controllare : preserve
*
* @param elm required dom element
* @param array (string) optional preserve element type
*/
Utility.setUnselectable = function  ( elm, preserve ) 
{
  if(elm && typeof(elm.tagName) != 'undefined')
  {
    // if(elm.tagName != 'INPUT' && elm.tagName != 'TEXTAREA' && elm.tagName != 'IFRAME') // Controllo sulla tipologia ELIMINATO
    if(elm.hasChildNodes())
    {
      for(var i = 0; i < elm.childNodes.length; i++)
      {
        Utility.setUnselectable( elm.childNodes[i], preserve );
      }
    }
    
    if ( preserve )
    {
      if ( preserve.indexOf( elm.tagName.toLowerCase() ) == -1 )
      {
        elm.unselectable = true;
      }  
    }
    else
    {
      elm.unselectable = true;
    }
  }
};

/**
* getElementsByAttribute
* Da sistemare : portare in json attibuti, utilizzare visitDomTree, ie6 (with strTagName=*)!
*
* @param node required oElm - Node element
* @param string required strTagName
* @param string required strAttributeName
* @param string required strAttributeValue
* @return array arrReturnElements
*/
Utility.getElementsByAttribute = function (oElm, strTagName, strAttributeName, strAttributeValue){
    var arrElements = (strTagName == "*" && document.all)? document.all : oElm.getElementsByTagName(strTagName);
    var arrReturnElements = new Array();
    var oAttributeValue = (typeof strAttributeValue != "undefined")? new RegExp("(^|\\s)" + strAttributeValue + "(\\s|$)") : null;
    var oCurrent;
    var oAttribute;
    for(var i=0; i<arrElements.length; i++){
        oCurrent = arrElements[i];
        oAttribute = oCurrent.getAttribute(strAttributeName);
        if(typeof oAttribute == "string" && oAttribute.length > 0){
            if(typeof strAttributeValue == "undefined" || (oAttributeValue && oAttributeValue.test(oAttribute))){
                arrReturnElements.push(oCurrent);
            }
        }
    }
    return arrReturnElements;
};

Utility.isChildOf = function ( elm, parent )
{
  while( (elm=elm.parentNode) != null ) if ( elm === parent ) return true;
  return false;
};

/**
* Cross browser method for creating new DOM nodes with name attributes. This
* gets around an Internet Explorer bug that prevents that get the name property
* assigned to them and their values aren't sent when the form submits.
*
* @param string required Node name, like "div" or "input"
* @param string required Value of the name attribute
* @return object New DOM node
*/
Utility.createElement = function (nodeName, name, enctype) 
{
  var node;
  try 
  {
    node = Utility.createElementMsie(nodeName, name, enctype);
    createElement = Utility.createElementMsie;
  } 
  catch (e) 
  {
    node = Utility.createElementStandard(nodeName, name, enctype);
    createElement = Utility.createElementStandard;
  }
  return node;
};

/**
* Code required by Internet Explorer when creating a new DOM node with the
* name attribute set.
*/
Utility.createElementMsie = function (nodeName, name, enctype) 
{
  if (!enctype) enctype = "";
  return document.createElement("<"+nodeName+" name="+name+" enctype="+enctype+">");
};

/**
* Code required by all other browsers that support web standards.
*/
Utility.createElementStandard = function (nodeName, name, enctype) 
{
  var node = document.createElement(nodeName);
  node.name = name;
  if (enctype)
  {
    node.setAttribute("enctype", enctype);
  }
  return node;
};

// Funzione per la creazione di cookie da javascript
Utility.createCookie = function (name,value,days) 
{
	if (days) 
  {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

// Funzione per la lettura dei cookie da javascript
Utility.readCookie = function (name)
{
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

/**
* loadSyncFile
*
* @param string required url
* @param boolean option xmlReturn
*/
Utility.loadSyncFile = function ( url, xmlReturn )
{
  var xmlHttp;
  try
  {
    // Oggetto per Firefox, Opera 8.0+, Safari
    xmlHttp = new XMLHttpRequest();
  }
  catch (e)
  {
    try
    {
      // ActiveX per Internet Explorer
      xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch (e)
    {
      try
      {
        // ActiveX per Internet Explorer < 6.0
        xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
      }
      catch (e)
      {
        return null;
      }
    }
  }
  
  xmlHttp.open("GET", url, false);
  xmlHttp.send(null);
  
  if (xmlHttp.status == 200) 
  {
    if ( xmlReturn === true ) return xmlHttp.responseXml;
    else return xmlHttp.responseText; 
  }
  else 
  {
    return null;
  }
};

// Funzione per la cancellazione di un cookie
Utility.eraseCookie = function (name) 
{
	createCookie(name,"",-1);
};

// Funzione per il controllo sui numeri ( float ed int )
Utility.is_numeric = function (val)
{
   if ((isNaN(val)) || (val.length == 0))
      return false;
   else
      return true;
};

// Funzione per il controllo sui numeri interi
Utility.is_int = function (val)
{
   if ((isNaN(val)) || (val.length == 0) || ( val.indexOf(".") != -1 ) )
      return false;
   else
      return true;
};

// Funzioni da controllare e ottimizzare
Utility.trim = function (stringa)
{ 
  while (stringa.substring(0,1) == ' ')
  {
      stringa = stringa.substring(1, stringa.length);
  }
  while (stringa.substring(stringa.length-1, stringa.length) == ' ')
  {
      stringa = stringa.substring(0,stringa.length-1);
  }
  return stringa;
};

/*
  Individuo la posizione del cursore in una textare o input text.             
  In generale
              -> 0 è inizio
              -> e node.value.length è la fine
*/
Utility.caret = function (node) 
{
  if(node.selectionStart) return node.selectionStart;
  else if(!document.selection) return 0;
  var c		= "\001";
  var sel	= document.selection.createRange();
  var txt	= sel.text;
  var dul	= sel.duplicate();
  var len	= 0;
  try{ dul.moveToElementText(node); }catch(e) { return 0; }
  sel.text	= txt + c;
  len		= (dul.text.indexOf(c));
  sel.moveStart('character',-1);
  sel.text	= "";
  return (len == -1)? node.value.length : len;
};

Utility.is_numeric = function ( val )
{
  if ( val===null || val===undefined ) return false;
      
  if ((isNaN(val)) || (val.length == 0)) return false;
  else return true;
};

Utility.removeAllChild = function ( nodo )
{
  while ( nodo.hasChildNodes() ) 
  { 
    nodo.removeChild( nodo.firstChild );
  }
};

Utility.getIframeValue = function ( obj )
{
  try
  {
    var val = obj.contentDocument.body.innerHTML;
  }
  catch(e)
  {
    var val = obj.contentWindow.document.body.innerHTML;
  }
  return val;
};

// Funzione Cross per recuperare gli elementi tramite il tag name
Utility.getElementsByNameCross = function ( name, tag )
{
  tag = tag || '*';
  
  var elem = document.getElementsByTagName(tag);
  var arr = new Array();
  
  for(i = 0,iarr = 0; i < elem.length; i++)
  {
    att = elem[i].getAttribute("name");
    if(att == name)
    {
      arr[iarr] = elem[i];
      iarr++;
    }
  }
  return arr;
};


// getPageCoords
Utility.getPageCoords = function ( element ) 
{
  var coords = { x: 0, y: 0};
  while (element) 
  {
    coords.x += element.offsetLeft;
    coords.y += element.offsetTop;
    element = element.offsetParent;
  }
  return coords;
};

// getScrollXY
Utility.getScrollXY = function ( ) 
{
  var scrollCoords = { x: 0, y: 0};
  if( typeof( window.pageYOffset ) == 'number' ) 
  {
    //Netscape compliant
    scrollCoords.y = window.pageYOffset;
    scrollCoords.x = window.pageXOffset;
  } 
  else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) 
  {
    //DOM compliant
    scrollCoords.y = document.body.scrollTop;
    scrollCoords.x = document.body.scrollLeft;
  } 
  else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) 
  {
    //IE6 standards compliant mode
    scrollCoords.y = document.documentElement.scrollTop;
    scrollCoords.x = document.documentElement.scrollLeft;
  }
  return scrollCoords;
};

Utility.getKeyID = function ( keyname )
{
  var key = ({
    "Backspace"   : 8,
    "Tab"         : 9,
    "Enter"       : 13,
    "Shift"       : 16,
    "Ctrl"        : 17,
    "Alt"         : 18,
    "Pause"       : 19,
    "Caps Lock"   : 20,
    "Escape"      : 27,
    "Page Up"     : 33,
    "Page Down"   : 34,
    "End"         : 35,
    "Arrow Left"  : 37,
    "Arrow Up"    : 38,
    "Arrow Right" : 39,
    "Arrow Down"  : 40,
    "Insert"      : 45,
    "Delete"      : 46  });
    
  if( key[keyname] ) return key[keyname];
  else return null;
};

Utility.getKeyName = function ( keyID )
{
  var key = ({
    "8"   : "Backspace",
    "9" 	: "Tab",
    "13" 	: "Enter",
    "16" 	: "Shift",
    "17" 	: "Ctrl",
    "18" 	: "Alt",
    "19" 	: "Pause",
    "20" 	: "Caps Lock",
    "27" 	: "Escape",
    "33" 	: "Page Up",
    "34" 	: "Page Down",
    "35" 	: "End",
    "37" 	: "Arrow Left",
    "38" 	: "Arrow Up",
    "39" 	: "Arrow Right",
    "40" 	: "Arrow Down",
    "45" 	: "Insert",
    "46" 	: "Delete"  });
    
  if( key[keyID] ) return key[keyID];
  else return null;
};

// by HTML.it - converte da decimale (0..255) a esadecimale (stringa a due caratteri)
Utility.DecToHex = function( n ){
  var hx=n.toString(16);
  if(hx.length==1) hx="0"+hx;
  return hx.toUpperCase();
};
  
// by HTML.it - converte da stringa esadecimale a numero decimale
Utility.HexToDec = function( s ){
  return parseInt(s,16);
};
  
// by HTML.it - riceve un vettore rgb in decimale e lo converte in stringa esadecimale
Utility.HEX = function( c ){
  return ("#" + Utility.DecToHex(c[0])+ Utility.DecToHex(c[1]) + Utility.DecToHex(c[2]));
};
  
// by HTML.it - restituisce la conversione esadecimale sotto forma di array di interi
Utility.RGB = function( c ){
  var r=new Array(3);
  if(c.charAt(0)=="#") c=c.substr(1,6); //elimina il cancelletto
  for(i=0;i<3;i++)
  r[i]=Utility.HexToDec(c.substr(i*2,2));
  return r;
};
  
Utility.cross = {
  w3: function(){ return !!(document.getElementById && document.createElement); }(),
  ie: function(){ return !!window.ActiveX; }()
};

Utility.manageClassName = function( a,o,c1,c2 )
{
  switch (a){
    case 'swap':
      o.className=!Utility.manageClassName('check',o,c1)?o.className.replace(c2,c1):o.className.replace(c1,c2);
    break;
    case 'add':
      if(!Utility.manageClassName('check',o,c1)){o.className+=o.className?' '+c1:c1;}
    break;
    case 'remove':
      var rep=o.className.match(' '+c1)?' '+c1:c1;
      o.className=o.className.replace(rep,'');
    break;
    case 'check':
      return new RegExp('\\b'+c1+'\\b').test(o.className)
    break;
  }
};
/*******************************************************************************
  [END UTILITY]  
*******************************************************************************/
/*******************************************************************************
  [OVERLOADIND OVERRING FUNZIONI DI UTILITÁ]  
*******************************************************************************/
sync                    = Utility.sync;
toArray                 = Utility.toArray;
typeOf                  = Utility.typeOf;

createXmlDom            = Utility.createXmlDom;
createElement           = Utility.createElement;
removeAllChild          = Utility.removeAllChild;

parseStrToXml           = Utility.parseStrToXml;
parseFileToXml          = Utility.parseFileToXml;
parseStrToJson          = Utility.parseStrToJson;
retriveRcFromXml        = Utility.retriveRcFromXml;
loadSyncFile            = Utility.loadSyncFile;

getElementsByClassName  = Utility.getElementsByClassName;
getElementsByClass      = Utility.getElementsByClass;
getElementsByAttribute  = Utility.getElementsByAttribute;
getElementsByNameCross  = Utility.getElementsByNameCross;
visitDomTree            = Utility.visitDomTree;
isChildOf               = Utility.isChildOf;
setUnselectable         = Utility.setUnselectable;

caret                   = Utility.caret;
trim                    = Utility.trim;
is_int                  = Utility.is_int;
is_numeric              = Utility.is_numeric;
eraseCookie             = Utility.eraseCookie;
readCookie              = Utility.readCookie;
createCookie            = Utility.createCookie;
getIframeValue          = Utility.getIframeValue;
is_numeric              = Utility.is_numeric;
getScrollXY             = Utility.getScrollXY;
getPageCoords           = Utility.getPageCoords;

getKeyID                = Utility.getKeyID;
getKeyName              = Utility.getKeyName;

DecToHex                = Utility.DecToHex;
HexToDec                = Utility.HexToDec;
HEX                     = Utility.HEX;
RGB                     = Utility.RGB;
cross                   = Utility.cross;

manageClassName         = Utility.manageClassName;
/*******************************************************************************
  [END OVERLOADIND OVERRING FUNZIONI DI UTILITÁ]  
*******************************************************************************/
/*******************************************************************************
  [JEvent OBJECT]  
*******************************************************************************/

$E  = JEvent = {};

/**
  [JEvent.eventStates] - Struttura dati listener 
  @obj        : OBJ DOM   --oggetto
  @evType     : STRING    --evento
  @funct      : FUNCTION  --funzione con bind
  @realFunct  : FUNCTION  --funzione originale
  @useCapture : BOOLEAN   --useCapture
  @opt        : JSON      --parametri
  
  Nota: La proprietà realFunct serve per confrontare le funzioni dei listenere
  nel metodo retriveIdx. I confronti non possono essere eseguiti con la funzione
  bindata, in quanto viene associato un indice differente e ciò comporta una replica
  della funzione di input ( con riferimento diverso dall'originale). Per poter
  eseguire correttamente il confronto dobbiamo confrontare i riferimenti alle
  funzioni orginali.
*/

$ES = JEvent.eventStates = [];

/** 
  [JEvent.add] - Metodo per l'aggiunta di un listener
  ritorna false in caso di problemi o nel caso il listener sia già presente
  altrimenti torna l'indice associato al listener
  ---
  @obj        : OBJ DOM   --oggetto
  @evType     : STRING    --evento
  @funct      : FUNCTION  --funzione
  @useCapture : BOOLEAN   --useCapture
  @opt        : JSON      --parametri
  ---
  
  Possiamo recuperare i parametri in 2 modi:
  - Tramite un terzo parametro passato come argomento ( oggetto ) che passa per
    valore numeri e var stringhe    
  - Tramite $ES che mantiene dei riferimenti
*/
JEvent.add = function(obj, evType, funct, useCapture, opt)
{
  // Calcolo idxEventStates 
  var idxEventStates = JEvent.eventStates.indexOf ( null );
  idxEventStates = ( (idxEventStates != -1) ) ? ( idxEventStates ) : (JEvent.eventStates.length);
  
  // Binding idxEventStates
  var realFunct = funct;
  var funct     = funct.bindEventListener( obj, idxEventStates, opt );
  
  // se il listener risulta gia' presente ritorno false
  if ( 
    JEvent.retriveIdx({
        "obj"         : obj,
        "evType"      : evType,
        "realFunct"   : realFunct,
        "useCapture"  : useCapture
      }) 
  ){
    return false;
  }
  
  if ( (obj["on" + evType]) && (obj["on" + evType] instanceof JCustomEvent) )
  {
    if( !(obj["on" + evType].add( funct )) ) return false;
  }
  else
  {
    try
    { 
      obj.addEventListener( evType, funct, useCapture );   
    }
    catch(e)
    {
      try
      {
        obj.attachEvent("on" + evType, funct);
      }
      catch(e)
      {
        return false;
      }
    }
  }
  
  // Aggiunta informazioni in eventStates
  JEvent.eventStates[idxEventStates] = 
    ({ 
      "obj"         : obj, 
      "evType"      : evType,
      "realFunct"   : realFunct,
      "funct"       : funct,
      "useCapture"  : useCapture,
      "opt"         : opt,
      "status"      : 0 
    });
  
  // Ritorno l'indice associato  
  return idxEventStates;  
};

/* 
  [JEvent.deactive] - Metodo ...
*/
JEvent.deactive = function( JSON )
{
  var arrIdxListener = JEvent.retriveIdx( JSON );
  
  if ( arrIdxListener )
  {
    var esito = true;
    
    for ( i=0;i<arrIdxListener.length;i++)
    {
      esito = ( JEvent.deactiveIdx ( arrIdxListener[i] ) ) ? ( esito ) : ( false ) ;
    }
    
    return esito;
  }
  else
  {
    return false;
  }
};

/* 
  [JEvent.deactiveIdx] - Metodo per la disattivazione di un listener (idx)
  Ritorna false se idx non esiste nell'array altrimenti true.
  ---
  @idx : INTEGER   --indice
*/
JEvent.deactiveIdx = function( idx )
{
  if ( JEvent.eventStates[idx] )
  {
    JEvent.eventStates[idx].status = 1;
    return true;
  }
  else
  {
    return false;
  }
};

/* 
  [JEvent.active] - Metodo ....
*/
JEvent.active = function( JSON )
{
  var arrIdxListener = JEvent.retriveIdx( JSON );
  
  if ( arrIdxListener )
  {
    var esito = true;
    
    for ( i=0;i<arrIdxListener.length;i++)
    {
      esito = ( JEvent.activeIdx ( arrIdxListener[i] ) ) ? ( esito ) : ( false ) ;
    }
    
    return esito;
  }
  else
  {
    return false;
  }
};

/* 
  [JEvent.activeIdx] - Metodo per l'attivazione di un listener (idx)
  Ritorna false se idx non esiste nell'array altrimenti true
  ---
  @idx : INTEGER   --indice
*/
JEvent.activeIdx = function( idx )
{
  if ( JEvent.eventStates[idx] )
  {
    JEvent.eventStates[idx].status = 0;
    return true;
  }
  else
  {
    return false;
  }
};

/* 
  [JEvent.retriveIdx] - Metodo per il retrive indice di un listener
  Ritorna false se non viene trovato nessun elemento altrimenti l'array degli 
  indici restituiti. ( ! da completare )
  ---
  @JSON  : OBJ DOM   --oggetto
*/
JEvent.retriveIdx = function( JSON )
{
  var tempArrIdx = [];   
  
  for ( idx=0; idx<JEvent.eventStates.length; idx++  )
  {
    if ( JEvent.eventStates[idx] )
    {
      var pushing = true;
      
      for ( param in  JSON )
      {
        pushing = ( JSON[param] != JEvent.eventStates[idx][param] ) ? ( false ) : ( pushing ) ; 
      }
      
      if ( pushing ) tempArrIdx.push( idx );
    }
  }

  return ( tempArrIdx.length == 0) ? ( null ) : ( tempArrIdx );
};

/* 
  [JEvent.retriveListenerInformation] - Metodo per il retrive informazioni
  Ritorna false se idx non esiste nell'array altrimenti il JSON contente le informazioni
  sul listener idx
  ! forse inutile visto eventStates e' pubblico
  ---
  @idx : INTEGER   --indice
*/
/*
JEvent.retriveListenerInformation = function( idx )
{
  if ( JEvent.eventStates[idx] )
  {
    return JEvent.eventStates[idxEventStates];
  }
  else
  {
    return false;
  }
};
*/

/* 
  [JEvent.remove] - Metodo per la rimozioni di un array di listener
  Ritorna false in caso di problemi altrimenti true se tutte le rimozioni avviengono
  con successo.
  ---
  @arrIdx     : ARRAY[INTEGER]   --array interi indici listener
*/
JEvent.remove = function( arrIdx )
{
  var esito = true;
  if ( typeOf ( arrIdx ) == 'array' ) 
  {
    for (i=0;i<arrIdx.length;i++)
    {
      esito = ( JEvent.removeIdx ( arrIdx[i] ) ) ? ( esito ) : ( false );
    }
    return esito;
  }
  return false;
};

/* 
  [JEvent.removeIdx] - Metodo per la rimozioni di un listener
  Ritorna false se idx non esiste o se si verificano problemi altrimenti true 
  se la rimozione del lister avviene con successo.
  ---
  @idx : INTEGER   --indice
*/
JEvent.removeIdx = function( idx )
{ 
  if ( JEvent.eventStates[idx] )
  { 
    var attEv = JEvent.eventStates[idx];
    
    if ( (attEv.obj["on" + attEv.evType]) && (attEv.obj["on" + attEv.evType] instanceof JCustomEvent) )
    {
      if( !(attEv.obj["on" + attEv.evType].remove( attEv.funct )) ) return false;
    }
    else
    {
      try
      {
        attEv.obj.removeEventListener(
            attEv.evType, 
            attEv.funct, 
            attEv.useCapture
          );
      }
      catch(e)
      {
        try
        {
          attEv.obj.detachEvent(
              "on" + attEv.evType, 
              attEv.funct
            );
        }
        catch(e)
        {
          return false;
        }
      }
    }
    
    JEvent.eventStates[idx] = null;
    return true;  
  }
  
  return false;
};

/* 
  [JEvent.fire] - Metodo per lanciare un evento.
  Ritorna false in caso di problemi, altrimenti true.
  ---
  @obj        : OBJ DOM   --oggetto
  @evType     : STRING    --evento
  @eJson      : JSON      --parametri evento
*/
JEvent.fire = function (obj, evType, eJson)
{
  if ( (obj["on" + evType]) && (obj["on" + evType] instanceof JCustomEvent) )
  {
    obj["on" + evType].fire( eJson );
    return true;
  }
  else
  {
    try{
        obj.fireEvent("on"+evType);
        return true;
    }
    catch(e)
    {
      var fireEvent = window.document.createEvent("UIEvent");   // KeyEvent  e MouseEvent sono sottoclassi
      fireEvent.initEvent(evType, false, true);                 // ci sono anche altre funzioni da capire il funzionamento: false -> bubbling true -> canceleable
      obj.dispatchEvent(fireEvent);
      return true;
    }
  }  
  return false;
};

/* 
  [JEvent.fireIdx] - Metodo per lanciare un evento
  Ritorna false in caso di problemi, altrimenti true.
  ---
  @obj        : OBJ DOM   --oggetto
  @evType     : STRING    --evento
  @eJson      : JSON      --parametri evento
*/ 
JEvent.fireIdx = function ( idx, eJson )
{
  if ( JEvent.eventStates[idx] )
  {
    return JEvent.fire( 
        JEvent.eventStates[idx].obj, 
        JEvent.eventStates[idx].evType,
        eJson 
      );
  }
  else
  {
    return false;
  }
};

/* 
  [JEvent.preventDefault] - Metodo per annullare l'azione HTML di default
  Ritorna false in caso di problemi, altrimenti true.
  ---
  @evt  : EVENT OBJ   --oggetto evento scatenato dalla funzione 
*/
JEvent.preventDefault = function ( evt )
{
  try
  {
    evt.preventDefault();   // FF
  }
  catch(err)
  {
    try
    {
      evt.returnValue = false;  // IExplorer ( non sempre c'è un azione di default con il try se non c'è non sollevo l'errore)
    }
    catch(e)
    { 
      return false; 
    }
  }
  return true;
};

/* 
  [JEvent.getTarget] - Metodo per il recupero cross del target dato un evento scatenato
  Ritorna null in caso di problemi, altrimenti il target.
  ---
  @evt  : EVENT OBJ   --oggetto evento scatenato dalla funzione 
*/
JEvent.getTarget = function ( evt )
{
  if( !evt ) return null;
  
  var relTarg = null;
   
  if (evt.target) relTarg = evt.target;
  else if (evt.srcElement) relTarg = evt.srcElement;
  if (relTarg.nodeType == 3) relTarg = relTarg.parentNode; // defeat Safari bug
  
  return relTarg;
};
/*******************************************************************************
  [END JEvent OBJECT]  
*******************************************************************************/
/*******************************************************************************
  [JCustomEvent OBJECT]  
*******************************************************************************/
JCustomEvent = function ( eventName )
{
  this.eventName  = eventName
  this.fn         = [];
};

JCustomEvent.prototype.fire = function ( eJson )
{
  //for (i=0;i<this.fn.length;i++) this.fn[i]();
  var eJson = eJson || {};
  for (i=0;i<this.fn.length;i++) this.fn[i]( eJson );
};

JCustomEvent.prototype.add = function ( funct )
{
  // verificare se disattivare controllo di pre-esistenza funzione
  for (i=0;i<this.fn.length;i++)
  { 
    if(this.fn[i]===funct) return false;
  }
  this.fn.push( funct );
  return true;
};

JCustomEvent.prototype.remove = function ( funct )
{
  for (i=0;i<this.fn.length;i++)
  {
    if( this.fn[i]===funct )
    {
      this.fn.remove(i);
      return true;
    }
    return false;
  }
};
/*******************************************************************************
  [END JCustomEvent OBJECT]  
*******************************************************************************/
/*******************************************************************************
  [JAjax OBJECT]  
*******************************************************************************/
$A = function( parameters )
{
  return new JAjax ( parameters );
};

JAjax = function( parameters )
{
  this.XHR          = null;
  this.ttl          = null;
  this.queryString  = null;
  this.method       = null;
  this.responseType = null;
  this.action       = null;
  this.cache        = null;
  this.operation    = null; 
  this.errOperation = null;
  this.localState   = null;
  this.lock         = null;
   
  this.init( parameters );
};

JAjax.prototype.init = function( parameters )
{
  var xmlHttp;
  try
  {
    // Oggetto per Firefox, Opera 8.0+, Safari
    xmlHttp = new XMLHttpRequest();
  }
  catch (e)
  {
    try
    {
      // ActiveX per Internet Explorer
      xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch (e)
    {
      try
      {
        // ActiveX per Internet Explorer < 6.0
        xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
      }
      catch (e)
      {
        return false;
      }
    }
  }
  
  parameters = ( parameters ) ? ( parameters ) : ( {} );
  
  this.XHR          = xmlHttp;
  this.ttl          = parameters["ttl"] || 600000;
  this.method       = parameters["method"] || "GET";
  this.responseType = parameters["responseType"] || "TEXT";
  this.action       = parameters["action"] || "";
  this.cache        = parameters["cache"] || true;
  this.operation    = parameters["operation"] || null;
  this.errOperation = parameters["errOperation"] || displayError; 
  this.localState   = parameters["localState"] || true;
  this.lock         = parameters["lock"] || false;
  this.queryString  = "";
  
  return true;
};


JAjax.prototype.addQueryString = function ( key,value )
{
  if (this.queryString != "") this.queryString += "&";
  // EncodeUri oltre che a proteggere l'invio dei dati in get/post da caratteri
  // particolare, converte il tutto in utf8 per l'invio corretto.
  this.queryString += key + "=" + encodeURIComponent(value);
};


JAjax.prototype.sendData = function()
{
  if ( ( !JAjax.globalState ) || ( !this.localState )  || ( this.lock ) )
  {
    return false;
  }
  
  // Closure
  var istanceJA = this;
  
  istanceJA.localState = false;
  
  var checkTime;          // Oggetto per il controllo del tempo
  var firstCheck = true;  // Semaforo per il controllo del tempo
  
  // Devo costruire il corretto passaggio di dati per GET/POST
  var link    = ( istanceJA.method.toUpperCase() == "POST" ) ? istanceJA.action : istanceJA.action+"?"+istanceJA.queryString ;
  var qstring = ( istanceJA.method.toUpperCase() == "POST" ) ? istanceJA.queryString : "" ;
  
  // Sistema di protezione da cache
  if ( (istanceJA.method.toUpperCase() == "GET") && (istanceJA.cache) )
  {
    var data = new Date();
    link += "&tstamp=" + encodeURIComponent(data.getHours() + data.getMinutes() + data.getSeconds() );
  }
  
  // Memorizzo l'istante della chiamata ajax
  var dateCall = new Date();
  var startCall = dateCall.getTime();
  
  // Imposto gli header per la chiamata
  istanceJA.XHR.open( istanceJA.method, link, true );
  
  // Per le chiamte POST devo aggiungere l'intestazione corretta
  if (istanceJA.method.toUpperCase() == "POST")
  {
    istanceJA.XHR.setRequestHeader("content-type", "application/x-www-form-urlencoded");
  }
  
  // Questa intestazione va aggiunta per ciascuna connessione
  istanceJA.XHR.setRequestHeader("connection", "close");
  
  // Imposto la funzione di controllo dello stato della chiamata ajax
  istanceJA.XHR.onreadystatechange = function()
  {
    if ( istanceJA.XHR.readyState === readyState.COMPLETATO )
    {
      checkTime = function(){};
      
      if( statusText[istanceJA.XHR.status] === "OK" )
      {
        if ( istanceJA.responseType.toUpperCase() === "XML" )
        {
          istanceJA.localState = true;
          istanceJA.operation ( istanceJA.XHR.responseXML );
        }
        else
        {
          istanceJA.localState = true;
          istanceJA.operation ( istanceJA.XHR.responseText );
        }
      }
      else
      {
        istanceJA.localState = true;
        istanceJA.errOperation ( statusText[istanceJA.XHR.status] );
      }
    }
    else if( firstCheck )
    {
      firstCheck = false;
      
      checkTime = function()
        {
          dateCurrent = new Date();
          currentCall = dateCurrent.getTime();
      
          if ( (currentCall - startCall) > istanceJA.ttl )
          {
            istanceJA.XHR.onreadystatechange = function(){ return false; };
            istanceJA.XHR.abort();
            istanceJA.localState = true;
          }
          else
          {
            setTimeout(checkTime, 100);
          }
        };
      checkTime();  
    }
  };
  
  // Effettuo la chiamata ajax
  istanceJA.XHR.send(qstring);
};

JAjax.globalState = true;

function displayError(){};

// Oggetto per la verifica dello stato
var readyState = {
  INATTIVO: 0,
  INIZIALIZZATO: 1,
  RICHIESTA: 2,
  RISPOSTA: 3,
  COMPLETATO: 4
};

// Array descrittivo dei codici restituiti dal server
var statusText = new Array();
statusText[0] = "Richiesta Fallita. Riprovare più tardi"; // Aggiunta per Abort
statusText[100] = "Continue";
statusText[101] = "Switching Protocols";
statusText[200] = "OK";
statusText[201] = "Created";
statusText[202] = "Accepted";
statusText[203] = "Non-Authoritative Information";
statusText[204] = "No Content";
statusText[205] = "Reset Content";
statusText[206] = "Partial Content";
statusText[300] = "Multiple Choices";
statusText[301] = "Moved Permanently";
statusText[302] = "Found";
statusText[303] = "See Other";
statusText[304] = "Not Modified";
statusText[305] = "Use Proxy";
statusText[306] = "(unused, but reserved)";
statusText[307] = "Temporary Redirect";
statusText[400] = "Bad Request";
statusText[401] = "Unauthorized";
statusText[402] = "Payment Required";
statusText[403] = "Forbidden";
statusText[404] = "Not Found";
statusText[405] = "Method Not Allowed";
statusText[406] = "Not Acceptable";
statusText[407] = "Proxy Authentication Required";
statusText[408] = "Request Timeout";
statusText[409] = "Conflict";
statusText[410] = "Gone";
statusText[411] = "Length Required";
statusText[412] = "Precondition Failed";
statusText[413] = "Request Entity Too Large";
statusText[414] = "Request-URI Too Long";
statusText[415] = "Unsupported Media Type";
statusText[416] = "Requested Range Not Satisfiable";
statusText[417] = "Expectation Failed";
statusText[500] = "Internal Server Error";
statusText[501] = "Not Implemented";
statusText[502] = "Bad Gateway";
statusText[503] = "Service Unavailable";
statusText[504] = "Gateway Timeout";
statusText[505] = "HTTP Version Not Supported";
statusText[509] = "Bandwidth Limit Exceeded";
/*******************************************************************************
  [END JAjax OBJECT]  
*******************************************************************************/
})();   

/*************************************************************************[info]
  OBJECT:               GoogleMap.js 
  REQUIRED:             eXtend
  DATA:                 29/10/2008
  COMPANY:              Onlime S.n.c.
 
  VERS:                 1.0
  LAST EDIT:            15/09/09
  
  PURPOSE:            GoogleMap object
  
  TODO:                 
    - marker possibilita` parametro zoom
    - ricreare procedura per crazione markers, ottenendo:
      .codice meno complesso
      .codice meno frammentato su + funzioni
      .preservare in qualche modo le proprietà iniziali dall'array passato per la creazione
      .se il punto nn viene trovare creare sistema di n ritentativi con settimeout proporzionati
      .mantenere la correlazione fra gli indici dati in array passato e indici array oggetti markers          
    
  LIMITI:  
    - ...
*******************************************************************************/
(function(){
/*******************************************************************************
  [GOOGLEMAP OBJECT]  
*******************************************************************************/
var listenerGoogleMap = null; // event.listener

GoogleMap = function( obj, parameters )
{ 
  this.map                  = null;         // GMap2
  this.obj                  = null;         // DOM
  this.objLoaderMarkers     = null;         // DOM
  this.typeControl          = null;
  this.mapControl           = null;
  this.geocoder             = null;         // GClientGeocoder
  this.markers              = [];           // Array GMarker
  this.tmpArrMarkersDetail  = null;
  this.tabAccuracy          = new Array(2,4,6,10,12,13,16,16,17); 
  
  // Richiamo l'inizializzazione
  this.init( obj, parameters );
}

/** init
@obj
@parameters small_controls
@parameters default_area[zoom,luogo]
@parameters AjaxCall
@parameters loaderMarkers
@parameters setUIToDefault
*/
GoogleMap.prototype.init = function( obj, parameters  )  //default_area, small_controls
{ 
  parameters = parameters || {};
   
  if ( !$(obj) ) return null;
  this.obj = $(obj);
  
  // sembra che risolvi i problemi di centramento punti..
  var opts = {
    size: new GSize( parseInt( $(obj).fn.css('width') ), parseInt( $(obj).fn.css('height') ) )
  };
  
  this.map = new GMap2( this.obj, opts );
  
  if ( !this.map ) return null;
  
  // Attach eventi window.unload
  if ( !listenerGoogleMap ) 
  {
    listenerGoogleMap = $E.add( window, "unload", GUnload, false ); // event.listener
  } 
  
  if ( parameters["setUIToDefault"] === true )
  {
    this.map.setUIToDefault();
  }
  else
  {
    // mappa - satellite - ibrida
    this.typeControl = new GMapTypeControl();
    this.map.addControl( this.typeControl );
    
    if ( parameters["small_controls"] === true )
    {
      // controller small
      this.mapControl = new GSmallMapControl();
      this.map.addControl( this.mapControl );
    }
    else
    {
      // controller con barra vert
      this.mapControl = new GLargeMapControl();
      this.map.addControl( this.mapControl );
      
      // zoom box, in basso a dx
      this.map.addControl( new GOverviewMapControl(), new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(9, 9)) );
    }
  }
  
  this.geocoder = new GClientGeocoder();
  
  if ( parameters["default_area"] )
  {
    var fn = function(point) 
      {
        if (!point) 
        {
          //alert(default_area['luogo'] + " not found");
        } 
        else
        {                 
           var zoom = parameters["default_area"]["zoom"] || 3;
           this.map.setCenter( point , zoom );
        }
      }
    fn = fn.bind ( this );
       
    this.geocoder.getLatLng( parameters["default_area"]["luogo"], fn );  
  }
  else
  {
    
    // Milano ...
    //this.map.setCenter(new GLatLng(45.470364,9.19487), 7);
  }
  
  if ( parameters["loaderMarkers"] === true ) this.addLoaderMarkers();
  if ( parameters["AjaxCall"] )               this.extractingAjaxXmlData( parameters["AjaxCall"] );
};

// required response Xml
GoogleMap.prototype.extractingAjaxXmlData = function ( objAjax, callbackFn )
{
  if ( objAjax )
  {
    var objGoogleMap = this;  // Closure
    
    if ( !objAjax.operation )
    {
      objAjax.responseType = "XML";
      objAjax.operation = function( responseXml )
        {
          var arrData = retriveRcFromXml( "arrMarkers", responseXml );
          if ( arrData )
          {
            objGoogleMap.createMarkers( arrData, callbackFn );
          }
        };
    }  
    // Chiamata Ajax  
    objAjax.sendData();  
  }
};

GoogleMap.prototype.extractingAjaxJSONData = function ( objAjax, callbackFn ){};

GoogleMap.prototype.fitMap = function ( points ) 
{
  var bounds = new GLatLngBounds();
  for (var i=0; i< points.length; i++) {
  bounds.extend(points[i]);
  }
  this.map.setZoom( this.map.getBoundsZoomLevel(bounds) );
  this.map.setCenter( bounds.getCenter() );
};
  
/* */
GoogleMap.prototype.removeMapControl = function()
{ 
  if ( this.mapControl )
  {
    this.map.removeControl( this.mapControl );
  }
};

/* */
GoogleMap.prototype.centerMap = function ( area )
{
  var fn = function(point) 
    {
      if (!point) 
      {
        return false;
      } 
      else
      {
         var zoom = area[1] || 3;
         this.map.setCenter( point , zoom );  // closure ?
         return true;
      }
     };
  fn = fn.bind ( this );
     
  this.geocoder.getLatLng( area[0], fn );
};

GoogleMap.prototype.centerMapWithAccuracy = function( strLocation ) 
{
  if (this.geocoder) 
  {
    var fn = function(response) 
      {
        if(response.Status.code!=200)
        {
          // alert('"' + address + '" not found');
        } 
        else 
        {
          place = response.Placemark[0];
          accuracy = place.AddressDetails.Accuracy;
          this.map.setCenter(
            new GLatLng(place.Point.coordinates[1],
            place.Point.coordinates[0]), this.tabAccuracy[accuracy]   // closure ?
          );
        }
      }
    fn = fn.bind ( this );
      
    this.geocoder.getLocations( strLocation, fn );
  }
};

GoogleMap.prototype.bestZoomCenterToLocation = function( strLocation ) 
{
  if (this.geocoder) 
  {
    var fn = function(response) 
      {
        if(response.Status.code!=200)
        {
          // alert('"' + address + '" not found');
        } 
        else 
        {
          //var p = result.Placemark[0].Point.coordinates;
          // ===== Look for the bounding box of the first result =====
          var N = response.Placemark[0].ExtendedData.LatLonBox.north;
          var S = response.Placemark[0].ExtendedData.LatLonBox.south;
          var E = response.Placemark[0].ExtendedData.LatLonBox.east;
          var W = response.Placemark[0].ExtendedData.LatLonBox.west;
          var bounds = new GLatLngBounds(new GLatLng(S,W), new GLatLng(N,E));
          // Choose a zoom level that fits
          var zoom = this.map.getBoundsZoomLevel(bounds);
          this.map.setCenter(bounds.getCenter(),zoom);
        }
      }
    fn = fn.bind ( this );
      
    this.geocoder.getLocations( strLocation, fn );
  }
};

/* DA VERIFICARE */
GoogleMap.prototype.setMaxZoomCenter = function ( latlng ) 
{
  var objMap = this.map;
  objMap.getCurrentMapType().getMaxZoomAtLatLng( latlng, function(response) {
                                                        if (response && response['status'] == G_GEO_SUCCESS) 
                                                        {
                                                          objMap.setCenter(latlng, response['zoom']);
                                                          alert(response['zoom']);
                                                        }
                                                      }
                                            );
};

/* */
GoogleMap.prototype.addLoaderMarkers = function( idTxtObj )
{
  if ( ! $(idTxtObj) )
  {
    var spanLoader = createElement( "span" );
    if ( idTxtObj ) spanLoader.setAttribute( "id",idTxtObj ); 
    
    spanLoader.style.cssText = ("position:absolute;"
                              + "top:0;" 
                              + "left:0;"
                              + "z-index:2;"  
                              + "width:100%;" 
                              + "height:100%;"
                              + "color:#FFF;"
                              + "background:#000 url('"+PATH_GOOGLEMAP+"img/loader.gif') center center no-repeat;" 
                              + "display:none;");
    
    
    this.objLoaderMarkers = $( this.obj.appendChild( spanLoader ) ) ;
  }
};

/* */
GoogleMap.prototype.createMarkers = function( arrMarkersDetail, callbackFn )
{
  if ( callbackFn ) this.prcCreateMarkers.callbackFn = callbackFn;
  
  this.tmpArrMarkersDetail = arrMarkersDetail;
  
  if ( this.objLoaderMarkers ) this.objLoaderMarkers.fn.UI.openAndFadeIn(null,{"v":20});
  
  this.prcCreateMarkers( 0 );
};

/* */
GoogleMap.prototype.prcCreateMarkers = function( idx )
{
  if ( this.tmpArrMarkersDetail )
  { 
    if ( this.tmpArrMarkersDetail[idx] )
    {
      if ( this.objLoaderMarkers )
      {
        this.objLoaderMarkers.innerHTML = ("Please wait, loading marker ... " + (idx+1) + " / "+ this.tmpArrMarkersDetail.length);
      }
      
      this.createMarker( idx, this.tmpArrMarkersDetail[idx] );
    }
    else
    {
      this.tmpArrMarkersDetail = null;
      
      if ( this.objLoaderMarkers )
      {
        var fn = function () {
            this.objLoaderMarkers.value = "";
            this.objLoaderMarkers.fn.UI.fadeOutAndClose({"v":10});                    
          }.bind( this );
        
        fn = fn.bind( this );
        window.setTimeout( fn, 1000 ); // per evitare problemi simultaneata' fadeIn/fadeOut
      }
      
      if ( this.prcCreateMarkers.callbackFn )
      {
        var temp = this.prcCreateMarkers.callbackFn;
        this.prcCreateMarkers.callbackFn = null;
        temp();
      }  
    }
  }
};

GoogleMap.prototype.createMarkers.callbackFn = null;

/** createMarker
@indice
@markerDetail address
@markerDetail icon
@markerDetail title
@markerDetail hide
@markerDetail setcenter
@markerDetail panTo
@markerDetail description
@markerDetail cbFn
*/ 
GoogleMap.prototype.createMarker = function ( indice, markerDetail ) 
{
  if (this.geocoder) 
  {
    var managerFunction = function( idx, point ) 
      {
        if (!point) 
        {
          alert( "'" + markerDetail["address"] + "' non riesce ad essere localizzato sulla mappa.");
          this.markers[idx] = null;
          //this.prcCreateMarkers( idx );
        } 
        else 
        { 
          var colorIcon = null;
          
          if( !markerDetail["icon"] )
          {
            // Creazione icona marker di default
            colorIcon = new GIcon(G_DEFAULT_ICON);
          }
          else
          {
            // Creazione icona marker & setting proprietá
            colorIcon = new GIcon();
            
            if( typeOf( markerDetail["icon"] ) == "string" )
            {
              // costruzione json ( x retrocompatibilità )
              var tmpJson = ({  image : markerDetail["icon"],
                                iconSize    : new GSize(32, 32),
                                iconAnchor  : new GPoint(15, 31) });
              
              markerDetail["icon"] = tmpJson;
            }
            
            // elaborazione su json
            for( var property in markerDetail["icon"] ) 
            { 
              //alert( property +":"+ markerDetail["icon"][property] );
              colorIcon[property] = markerDetail["icon"][property];
            }
            
            /*  ESEMPIO PROPRIETÀ 
            colorIcon.image             = markerDetail["icon"];
            colorIcon.iconSize          = new GSize(32, 32);
            colorIcon.iconAnchor        = new GPoint(15, 31);
            colorIcon.infoWindowAnchor  = new GPoint(15, 9);
            colorIcon.shadowSize        = new GSize(37, 34);
            colorIcon.shadow            = null;
            colorIcon.infoShadowAnchor  = new GPoint(18, 25);
            */
          }
                          
          // Set up Oggetto GMarkerOptions
          var markerOptions = { icon:colorIcon };
          if ( markerDetail["title"] ) markerOptions["title"] = markerDetail["title"];
          
          var marker = new GMarker(point,markerOptions);
          this.map.addOverlay(marker);
          
          //addoverlay
          //GEvent.addListener(source:Object, event:String, handler:Function) 
          
          if ( markerDetail["hide"] == 0 ) marker.hide();
          
          /* Centramento su punto e zoom se viene richiesto il centramento */
          if ( markerDetail["setcenter"] ) 
          {
            this.map.setCenter( point,14 );
          }
          
          /* panTo se viene richiesto l'effetto */
          if ( markerDetail["panTo"] ) 
          {
            this.map.panTo( point );
          }
          
          /* Attach evento onclick su marker se vi è descrizione */
          if ( markerDetail["description"] )
          {
            var fn = function()
            {
              //var opts = {pixelOffset:new GSize(32,5), maxWidth:250};
              var opts = null;
              marker.openInfoWindowHtml(markerDetail["description"],opts); 
            }
            GEvent.addListener( marker, "click", fn );  
          }
          
          // In caso di richiesta di callbackFn la attacco al click
          if ( markerDetail["cbFn"] )
          {
            if ( typeof( markerDetail["cbFn"] ) =='string' )
            {
              //...
            }  
            GEvent.addListener( marker, "click", markerDetail["cbFn"] );
          }
           
          this.markers[idx] = marker;
        }
        
        var fnNext = function( j ){ this.prcCreateMarkers( j ); }.bind( this, idx+1 );
        window.setTimeout( fnNext, 100 );
      };
      
    managerFunction = managerFunction.bind( this,indice );
      
    this.geocoder.getLatLng( markerDetail["address"], managerFunction );
  }
};
/*******************************************************************************
  [END GOOGLEMAP OBJECT]  
*******************************************************************************/
})();
/*************************************************************************[info]
  OBJECT:               LightWindow
  REQUIRED:             Framework eXtend (v2) (eXtend)
  DATA:                 04/03/2009
  COMPANY:              Onlime S.n.c.
 
  VERS:                 1.0
  LAST EDIT:            15/10/2009
  
  TODO:                 
    - Inline Block cross
      http://code.google.com/p/doctype/wiki/ArticleInlineBlock              
    
  LIMITI:  
    - Limite ie non riesce ad eseguire correttamente i fade su png di conseguenza
    i metodi showWithFade e hideWithFade non sono correttemente supportati 
    (nel caso occorre fissare come per la renderizzazione dei font un colore 
    di background all'oggetto)
    
    - Eseguito fix per ie per problema legato al click sul divWindow, riconosce 
    l'intera superficie dell'elemento solo se impostato un colore di background 
    nn transparent o una immagine anche se inesistente.
*******************************************************************************/
(function() {
/*******************************************************************************
  [LightWindow OBJECT]  
*******************************************************************************/

/**
*	@class LightWindow 
*	@param {Object} obj
*	@param {Object} parameters
*/
LightWindow = function ( obj, parameters )
{
  this.obj                  = null;
  this.divWindowTrasparent  = null;
  this.divWtOpacity         = null;
  this.divWindow            = null;
  this.idxEvKeyUp           = null;
  
  // JCustomEvent definition
  this.onaftershow        = new JCustomEvent( "aftershow" );
  this.onafterhide        = new JCustomEvent( "afterhide" );
  this.onafterreposition  = new JCustomEvent( "afterreposition" );
  this.onexit             = new JCustomEvent( "exit" );
  
  // init
  LightWindow.prototype.init.apply ( this, [obj,parameters] );
};

/**
*	init LightWindow
*	@param {Object} obj
*	@param {Object} parameters
*/
LightWindow.prototype.init = function ( obj, parameters )
{ 
  parameters = parameters || {};
  parameters["opacity"]     = parseInt( parameters["opacity"] ) || 70;
  parameters["bgColor"]     = parameters["bgColor"] || "#F0F0F0";
  
  this.divWtOpacity       = parameters["opacity"];
  
  var divWindowTrasparent = createElement( "div" );
  var divWindow           = createElement( "div" );
  
  this.divWindowTrasparent  = document.body.appendChild( divWindowTrasparent );
  this.divWindow            = document.body.appendChild( divWindow );
  
  this.divWindowTrasparent.style.cssText = (  "height:100%;"
                                            + "display:none;"
                                            + "width:100%;"
                                            + "top:0px;"
                                            + "left:0px;"
                                            + "z-index:100;"
                                            + "background:"+parameters["bgColor"]+";"
                                            + "position:fixed;" );
                          
  $( this.divWindowTrasparent ).fn.UI.setOpacity( parameters["opacity"] );
  
  this.divWindow.style.cssText = (  "height:100%;"
                                  + "display:none;"
                                  + "width:100%;"
                                  + "top:0px;"
                                  + "left:0px;"
                                  + "background:url('inesistente');"  // Fix ie 
                                  + "z-index:101;"
                                  + "position:fixed;" );
  
  if( obj ) this.swapObject( obj );
  
  
  var objLightWindow = this;  // closure
  
  // fnExit
  var fnExit = function ( e ){
    var relTarg = $E.getTarget( e );
    if( !isChildOf( relTarg, this ) ) objLightWindow.onexit.fire();
  };
  $E.add(this.divWindow,"click",fnExit,false);  // attach event
  
  // fnKeyUp
  var fnKeyUp = function ( e ){
    if( e.keyCode == getKeyID( "Escape" ) ) objLightWindow.onexit.fire();
  };
  this.idxEvKeyUp = $E.add( document, "keyup", fnKeyUp, false); // attach event
  
  // deactiveIdx
  $E.deactiveIdx( this.idxEvKeyUp );
  
  // aftershow & afterhide event
  $E.add( objLightWindow, "aftershow", function(){ $E.activeIdx( this.idxEvKeyUp ); }, false );
  $E.add( objLightWindow, "afterhide", function(){ $E.deactiveIdx( this.idxEvKeyUp ); }, false);
                           
  return true;
};

/**
*	show LightWindow
*/
LightWindow.prototype.show = function ()
{
  $(this.divWindow).fn.UI.open();
  $(this.divWindowTrasparent).fn.UI.open();
  
  // Fire onload Gallery Event
  this.onaftershow.fire();
};


/**
*	showWithFade LightWindow
*/
LightWindow.prototype.showWithFade = function ()
{
  
  // Fire onload Gallery Event
  var objLightWindow = this;
  var cbFn = function(){ objLightWindow.onaftershow.fire(); };
  
  $(this.divWindowTrasparent).fn.UI.openAndFadeIn(  null, 
                                                    { "lim_opacity": objLightWindow.divWtOpacity, "a": 0.7, "v": 2 }, 
                                                    null 
                                                 );
  $(this.divWindow).fn.UI.openAndFadeIn(  null, 
                                          { "a": 0.3, "v": 2 }, 
                                          cbFn 
                                       );
};

/**
*	hideWithFade LightWindow
*/
LightWindow.prototype.hideWithFade = function ()
{
  // Fire onload Gallery Event
  var objLightWindow = this;
  var cbFn = function(){ objLightWindow.onafterhide.fire(); };
  
  $(this.divWindow).fn.UI.fadeOutAndClose( { "a": 0.7, "v": 3 }, 
                                           null, 
                                           null 
                                        );
  
  $(this.divWindowTrasparent).fn.UI.fadeOutAndClose(  { "a": 0.7, "v": 3 }, 
                                                      null, 
                                                      cbFn 
                                                   );
};

/**
*	hide LightWindow
*	@param {Object} parameters
*/
LightWindow.prototype.hide = function ()
{
  $(this.divWindow).fn.UI.close();
  $(this.divWindowTrasparent).fn.UI.close();
  
  // Fire onload Gallery Event
  this.onafterhide.fire();
};


/**
*	changeObjectWithFade LightWindow
*	@obj {Object} obj
*/
//LightWindow.prototype.changeObjectWithFade = function ( obj ){};

/**
*	changeObject LightWindow
*	@obj {Object} obj
*/
LightWindow.prototype.swapObject = function ( obj )
{ 
  var obj = $(obj);
  obj.style.display = ( obj.fn.css("width") == "auto" ) ? ("inline-block") : ("block");
  
  var h = ( parseFloat(obj.offsetHeight)/2 );
  var w = ( parseFloat(obj.offsetWidth)/2 );
  
  if ( this.obj )
  {
    this.obj.parentNode.replaceChild( obj, this.obj );
    this.obj = obj;
  }
  else
  {
    this.obj = this.divWindow.appendChild( obj );
  }
  
  this.obj.style.position   = "absolute";
  this.obj.style.top        = "50%";
  this.obj.style.left       = "50%";
  this.obj.style.marginTop  = "-"+h+"px";
  this.obj.style.marginLeft = "-"+w+"px";
}

/**
*	reposition LightWindow
*/
LightWindow.prototype.reposition = function ( )
{ 
  var h = ( parseFloat(this.obj.offsetHeight)/2 );
  var w = ( parseFloat(this.obj.offsetWidth)/2 );
  
  this.obj.style.position   = "absolute";
  this.obj.style.top        = "50%";
  this.obj.style.left       = "50%";
  this.obj.style.marginTop  = "-"+h+"px";
  this.obj.style.marginLeft = "-"+w+"px";
  
  this.onafterreposition.fire();
}
/*******************************************************************************
  [END LightWindow OBJECT]  
*******************************************************************************/
/*******************************************************************************
  [LightWindow STATIC]  
*******************************************************************************/
LightWindow.obj                 = null;
LightWindow.divWindowTrasparent = null;
LightWindow.divWtOpacity        = null;
LightWindow.divWindow           = null;
LightWindow.idxEvKeyUp          = null;

// JCustomEvent definition
LightWindow.onaftershow        = new JCustomEvent( "aftershow" );
LightWindow.onafterhide        = new JCustomEvent( "afterhide" );
LightWindow.onafterreposition  = new JCustomEvent( "afterreposition" );
LightWindow.onexit             = new JCustomEvent( "exit" );

LightWindow.init = function ( obj, parameters )
{
  parameters = parameters || {};
  parameters["opacity"]     = parseInt( parameters["opacity"] ) || 70;
  parameters["bgColor"]     = parameters["bgColor"] || "#F0F0F0";
  
  LightWindow.divWtOpacity  = parameters["opacity"];
  
  var divWindowTrasparent = createElement( "div" );
  var divWindow           = createElement( "div" );
  
  LightWindow.divWindowTrasparent  = document.body.appendChild( divWindowTrasparent );
  LightWindow.divWindow            = document.body.appendChild( divWindow );
  
  LightWindow.divWindowTrasparent.style.cssText = ( "height:100%;"
                                                  + "display:none;"
                                                  + "width:100%;"
                                                  + "top:0px;"
                                                  + "left:0px;"
                                                  + "z-index:100;"
                                                  + "background:"+parameters["bgColor"]+";"
                                                  + "position:fixed;" );
                          
  $( LightWindow.divWindowTrasparent ).fn.UI.setOpacity( parameters["opacity"] );
  
  LightWindow.divWindow.style.cssText = ( "height:100%;"
                                        + "display:none;"
                                        + "width:100%;"
                                        + "top:0px;"
                                        + "left:0px;"
                                        + "background:url('inesistente');"  // Fix ie 
                                        + "z-index:101;"
                                        + "position:fixed;" );
  
  if( obj ) LightWindow.swapObject( obj );
  
  // fnExit
  var fnExit = function ( e ){
    var relTarg = $E.getTarget( e );
    if( !isChildOf( relTarg, this ) ) LightWindow.onexit.fire();
  };
  $E.add( LightWindow.divWindow, "click", fnExit, false );  // attach event
  
  // fnKeyUp
  var fnKeyUp = function ( e ){
    if( e.keyCode == getKeyID( "Escape" ) ) LightWindow.onexit.fire();
  };
  LightWindow.idxEvKeyUp = $E.add( document, "keyup", fnKeyUp, false ); // attach event
  
  // deactiveIdx
  $E.deactiveIdx( LightWindow.idxEvKeyUp );
  
  // aftershow & afterhide event
  $E.add( LightWindow, "aftershow", function(){ $E.activeIdx( LightWindow.idxEvKeyUp ); }, false );
  $E.add( LightWindow, "afterhide", function(){ $E.deactiveIdx( LightWindow.idxEvKeyUp ); }, false );
                           
  return true;
};

LightWindow.show = function ()
{
  $(LightWindow.divWindow).fn.UI.open();
  $(LightWindow.divWindowTrasparent).fn.UI.open();
  
  // Fire onload Gallery Event
  LightWindow.onaftershow.fire();
};

LightWindow.showWithFade = function ()
{
  // Fire onload Gallery Event
  var cbFn = function(){ LightWindow.onaftershow.fire(); };
  
  $(LightWindow.divWindowTrasparent).fn.UI.openAndFadeIn( null, 
                                                          { "lim_opacity": LightWindow.divWtOpacity, "a": 0.7, "v": 2 }, 
                                                          null 
                                                        );
  $(LightWindow.divWindow).fn.UI.openAndFadeIn( null, 
                                                { "a": 0.3, "v": 2 }, 
                                                cbFn 
                                              );
};

LightWindow.hideWithFade = function ()
{
  // Fire onload Gallery Event
  var cbFn = function(){ LightWindow.onafterhide.fire(); };
  
  $(LightWindow.divWindow).fn.UI.fadeOutAndClose( { "a": 0.7, "v": 3 }, 
                                                  null, 
                                                  null 
                                                );
  
  $(LightWindow.divWindowTrasparent).fn.UI.fadeOutAndClose( { "a": 0.7, "v": 3 }, 
                                                            null, 
                                                            cbFn 
                                                          );
};

LightWindow.hide = function ()
{
  $(LightWindow.divWindow).fn.UI.close();
  $(LightWindow.divWindowTrasparent).fn.UI.close();
  
  // Fire onload Gallery Event
  LightWindow.onafterhide.fire();
};

LightWindow.swapObject = function ( obj )
{
  var obj = $(obj);
  obj.style.display = ( obj.fn.css("width") == "auto" ) ? ("inline-block") : ("block");
  
  var h = ( parseFloat(obj.offsetHeight)/2 );
  var w = ( parseFloat(obj.offsetWidth)/2 );
  
  if ( LightWindow.obj )
  {
    LightWindow.obj.parentNode.replaceChild( obj, LightWindow.obj );
    LightWindow.obj = obj;
  }
  else
  {
    LightWindow.obj = LightWindow.divWindow.appendChild( obj );
  }
  
  LightWindow.obj.style.position   = "absolute";
  LightWindow.obj.style.top        = "50%";
  LightWindow.obj.style.left       = "50%";
  LightWindow.obj.style.marginTop  = "-"+h+"px";
  LightWindow.obj.style.marginLeft = "-"+w+"px";
};

LightWindow.reposition = function ()
{
  var h = ( parseFloat(LightWindow.obj.offsetHeight)/2 );
  var w = ( parseFloat(LightWindow.obj.offsetWidth)/2 );
  
  LightWindow.obj.style.position   = "absolute";
  LightWindow.obj.style.top        = "50%";
  LightWindow.obj.style.left       = "50%";
  LightWindow.obj.style.marginTop  = "-"+h+"px";
  LightWindow.obj.style.marginLeft = "-"+w+"px";
  
  LightWindow.onafterreposition.fire();
};
/*******************************************************************************
  [END LightWindow STATIC]  
*******************************************************************************/
})();

/*************************************************************************[info]
  OBJECT:               LightWindowT (with table)
  REQUIRED:             Framework eXtend (v2) (eXtend)
  DATA:                 04/03/2009
  COMPANY:              Onlime S.n.c.
 
  VERS:                 2.0
  LAST EDIT:            10/10/2009
  
  TODO:                 -
    
  LIMITI:  
    - Limite ie non riesce ad eseguire correttamente i fade su png di conseguenza
    i metodi showWithFade e hideWithFade non sono correttemente supportati 
    (nel caso occorre fissare come per la renderizzazione dei font un colore 
    di background all'oggetto)
    
    - Eseguito fix per ie per problema legato al click sul divWindow, riconosce 
    l'intera superficie dell'elemento solo se impostato un colore di background 
    nn transparent o una immagine anche se inesistente.
*******************************************************************************/
(function() {
/*******************************************************************************
  [LightWindowT OBJECT]  
*******************************************************************************/
/**
*	@class LightWindowT 
*	@param {Object} obj
*	@param {Object} parameters
*/
LightWindowT = function ( obj, parameters )
{
  this.obj                  = null;
  this.divWindowTrasparent  = null;
  this.divWtOpacity         = null;
  this.divWindow            = null;
  this.tableWindow          = null;
  this.trWindow             = null;
  this.tdWindow             = null;
  
  // JCustomEvent definition
  this.onaftershow        = new JCustomEvent( "aftershow" );
  this.onafterhide        = new JCustomEvent( "afterhide" );
  this.onafterreposition  = new JCustomEvent( "afterreposition" );
  this.onexit             = new JCustomEvent( "exit" );
  
  // init
  LightWindowT.prototype.init.apply ( this, [obj,parameters] );
};

/**
*	init LightWindowT
*	@param {Object} obj
*	@param {Object} parameters
*/
LightWindowT.prototype.init = function ( obj, parameters )
{ 
  parameters = parameters || {};
  parameters["opacity"]     = parseInt( parameters["opacity"] ) || 70;
  parameters["bgColor"]     = parameters["bgColor"] || "#F0F0F0";
  
  this.divWtOpacity       = parameters["opacity"];
  
  var divWindowTrasparent = createElement( "div" );
  var divWindow           = createElement( "div" );
  
  var myTable           = createElement("table");
  var myThead           = createElement("thead");
  myThead.style.height  = "0px";
  var myTfoot           = createElement("tfoot");
  myTfoot.style.height  = "0px";
  var myTbody           = createElement("tbody");
  var myRow             = createElement("tr");
  var myCell            = createElement("td");
  myTable.appendChild(myThead);
  myTable.appendChild(myTfoot);
  myTable.appendChild(myTbody);
  myTbody.appendChild(myRow);
  myRow.appendChild(myCell);
  
  this.tdWindow             = myCell;
  this.trWindow             = myRow;
  this.tableWindow          = divWindow.appendChild( myTable );
  this.divWindowTrasparent  = document.body.appendChild( divWindowTrasparent );
  this.divWindow            = document.body.appendChild( divWindow );
  
  this.divWindowTrasparent.style.cssText = (  "height:100%;"
                                            + "display:none;"
                                            + "width:100%;"
                                            + "top:0px;"
                                            + "left:0px;"
                                            + "z-index:100;"
                                            + "background:"+parameters["bgColor"]+";"
                                            + "position:fixed;" );
                          
  $( this.divWindowTrasparent ).fn.UI.setOpacity( parameters["opacity"] );
  
  this.divWindow.style.cssText = (  "height:100%;"
                                  + "display:none;"
                                  + "width:100%;"
                                  + "top:0px;"
                                  + "left:0px;"
                                  + "background:url('inesistente');"  // Fix ie
                                  + "z-index:101;"
                                  + "position:fixed;" );
  
  this.tableWindow.style.cssText = (  "height:100%;"
                                    + "width:100%;" ); 
  
  this.tdWindow.style.cssText = ( "height:100%;"
                                + "width:100%;"
                                + "vertical-align:middle;"
                                + "text-align:center;" ); // text-align:center for ie                                                                                                
  
  if( obj ) this.swapObject( obj );
  
  
  var objLightWindow = this;  // closure
  
  // fnExit
  var fnExit = function ( e ){
    var relTarg = $E.getTarget( e );
    if( !isChildOf( relTarg, this ) ) objLightWindow.onexit.fire();
  };
  $E.add(this.tdWindow,"click",fnExit,false);  // attach event
  
  // fnKeyUp
  var fnKeyUp = function ( e ){
    if( e.keyCode == getKeyID( "Escape" ) ) objLightWindow.onexit.fire();
  };
  this.idxEvKeyUp = $E.add( document, "keyup", fnKeyUp, false); // attach event
  
  // deactiveIdx
  $E.deactiveIdx( this.idxEvKeyUp );
  
  // aftershow & afterhide event
  $E.add( objLightWindow, "aftershow", function(){ $E.activeIdx( this.idxEvKeyUp ); }, false );
  $E.add( objLightWindow, "afterhide", function(){ $E.deactiveIdx( this.idxEvKeyUp ); }, false);
                           
  return true;
};

/**
*	show LightWindowT
*/
LightWindowT.prototype.show = function ()
{
  $(this.divWindow).fn.UI.open();
  $(this.divWindowTrasparent).fn.UI.open();
  
  // Fire onload Gallery Event
  this.onaftershow.fire();
};


/**
*	showWithFade LightWindowT
*/
LightWindowT.prototype.showWithFade = function ()
{
  
  // Fire onload Gallery Event
  var objLightWindowT = this;
  var cbFn = function(){ objLightWindowT.onaftershow.fire(); };
  
  $(this.divWindowTrasparent).fn.UI.openAndFadeIn(  null, 
                                                    { "lim_opacity": objLightWindowT.divWtOpacity, "a": 0.7, "v": 2 }, 
                                                    null 
                                                 );
  $(this.divWindow).fn.UI.openAndFadeIn(  null, 
                                          { "a": 0.3, "v": 2 }, 
                                          cbFn 
                                       );
};

/**
*	hideWithFade LightWindowT
*/
LightWindowT.prototype.hideWithFade = function ()
{
  // Fire onload Gallery Event
  var objLightWindowT = this;
  var cbFn = function(){ objLightWindowT.onafterhide.fire(); };
  
  $(this.divWindow).fn.UI.fadeOutAndClose( { "a": 0.7, "v": 3 }, 
                                           null, 
                                           null 
                                        );
  
  $(this.divWindowTrasparent).fn.UI.fadeOutAndClose(  { "a": 0.7, "v": 3 }, 
                                                      null, 
                                                      cbFn 
                                                   );
};

/**
*	hide LightWindowT
*	@param {Object} parameters
*/
LightWindowT.prototype.hide = function ()
{
  $(this.divWindow).fn.UI.close();
  $(this.divWindowTrasparent).fn.UI.close();
  
  // Fire onload Gallery Event
  this.onafterhide.fire();
};


/**
*	changeObjectWithFade LightWindowT
*	@obj {Object} obj
*/
//LightWindowT.prototype.changeObjectWithFade = function ( obj ){};

/**
*	changeObject LightWindowT
*	@obj {Object} obj
*/
LightWindowT.prototype.swapObject = function ( obj )
{ 
  var obj = $(obj);
  obj.style.display = ( obj.fn.css("width") == "auto" ) ? ("inline-block") : ("block");
  
  if ( this.obj )
  {
    //this.obj.parentNode.replaceChild( obj, this.obj );
    this.tdWindow.replaceChild( obj, this.obj );
    this.obj = obj;
  }
  else
  {
    this.obj = this.tdWindow.appendChild( obj );
  }
  
  // Centramento per Mozilla
  this.obj.style.marginLeft   = "auto";
  this.obj.style.marginRight  = "auto";
};

/**
*	reposition LightWindowT
*/
LightWindowT.prototype.reposition = function ( )
{ 
  this.onafterreposition.fire();
};
/*******************************************************************************
  [END LightWindowT OBJECT]  
*******************************************************************************/
/*******************************************************************************
  [LightWindowT STATIC]  
*******************************************************************************/
LightWindowT.obj                  = null;
LightWindowT.divWindowTrasparent  = null;
LightWindowT.divWtOpacity         = null;
LightWindowT.divWindow            = null;
LightWindowT.tableWindow          = null;
LightWindowT.trWindow             = null;
LightWindowT.tdWindow             = null;

// JCustomEvent definition
LightWindowT.onaftershow        = new JCustomEvent( "aftershow" );
LightWindowT.onafterhide        = new JCustomEvent( "afterhide" );
LightWindowT.onafterreposition  = new JCustomEvent( "afterreposition" );
LightWindowT.onexit             = new JCustomEvent( "exit" );

LightWindowT.init = function ( obj, parameters )
{ 
  parameters = parameters || {};
  parameters["opacity"]     = parseInt( parameters["opacity"] ) || 70;
  parameters["bgColor"]     = parameters["bgColor"] || "#F0F0F0";
  
  this.divWtOpacity       = parameters["opacity"];
  
  var divWindowTrasparent = createElement( "div" );
  var divWindow           = createElement( "div" );
  
  var myTable           = createElement("table");
  var myThead           = createElement("thead");
  myThead.style.height  = "0px";
  var myTfoot           = createElement("tfoot");
  myTfoot.style.height  = "0px";
  var myTbody           = createElement("tbody");
  var myRow             = createElement("tr");
  var myCell            = createElement("td");
  myTable.appendChild(myThead);
  myTable.appendChild(myTfoot);
  myTable.appendChild(myTbody);
  myTbody.appendChild(myRow);
  myRow.appendChild(myCell);
  
  LightWindowT.tdWindow             = myCell;
  LightWindowT.trWindow             = myRow;
  LightWindowT.tableWindow          = divWindow.appendChild( myTable );
  LightWindowT.divWindowTrasparent  = document.body.appendChild( divWindowTrasparent );
  LightWindowT.divWindow            = document.body.appendChild( divWindow );
  
  LightWindowT.divWindowTrasparent.style.cssText = (  "height:100%;"
                                                    + "display:none;"
                                                    + "width:100%;"
                                                    + "top:0px;"
                                                    + "left:0px;"
                                                    + "z-index:100;"
                                                    + "background:"+parameters["bgColor"]+";"
                                                    + "position:fixed;" );
                          
  $( LightWindowT.divWindowTrasparent ).fn.UI.setOpacity( parameters["opacity"] );
  
  LightWindowT.divWindow.style.cssText = (  "height:100%;"
                                          + "display:none;"
                                          + "width:100%;"
                                          + "top:0px;"
                                          + "left:0px;"
                                          + "background:url('inesistente');"  // Fix ie
                                          + "z-index:101;"
                                          + "position:fixed;" );
  
  LightWindowT.tableWindow.style.cssText = (  "height:100%;"
                                            + "width:100%;" ); 
  
  LightWindowT.tdWindow.style.cssText = ( "height:100%;"
                                        + "width:100%;"
                                        + "vertical-align:middle;"
                                        + "text-align:center;" ); // text-align:center for ie                                                                                                
  
  if( obj ) this.swapObject( obj );
  
  // fnExit
  var fnExit = function ( e ){
    var relTarg = $E.getTarget( e );
    if( !isChildOf( relTarg, this ) ) LightWindowT.onexit.fire();
  };
  $E.add(LightWindowT.tdWindow,"click",fnExit,false);  // attach event
  
  // fnKeyUp
  var fnKeyUp = function ( e ){
    if( e.keyCode == getKeyID( "Escape" ) ) LightWindowT.onexit.fire();
  };
  this.idxEvKeyUp = $E.add( document, "keyup", fnKeyUp, false); // attach event
  
  // deactiveIdx
  $E.deactiveIdx( LightWindowT.idxEvKeyUp );
  
  // aftershow & afterhide event
  $E.add( LightWindowT, "aftershow", function(){ $E.activeIdx( LightWindowT.idxEvKeyUp ); }, false );
  $E.add( LightWindowT, "afterhide", function(){ $E.deactiveIdx( LightWindowT.idxEvKeyUp ); }, false);
                           
  return true;
};

LightWindowT.show = function ()
{
  $(LightWindowT.divWindow).fn.UI.open();
  $(LightWindowT.divWindowTrasparent).fn.UI.open();
  
  // Fire onload Gallery Event
  LightWindowT.onaftershow.fire();
};

LightWindowT.showWithFade = function ()
{
  // Fire onload Gallery Event
  var cbFn = function(){ LightWindowT.onaftershow.fire(); };
  
  $(LightWindowT.divWindowTrasparent).fn.UI.openAndFadeIn(  null, 
                                                            { "lim_opacity": LightWindowT.divWtOpacity, "a": 0.7, "v": 2 }, 
                                                            null 
                                                         );
  $(LightWindowT.divWindow).fn.UI.openAndFadeIn(  null, 
                                                  { "a": 0.3, "v": 2 }, 
                                                  cbFn 
                                               );
};

LightWindowT.hideWithFade = function ()
{
  // Fire onload Gallery Event
  var cbFn = function(){ LightWindowT.onafterhide.fire(); };
  
  $(LightWindowT.divWindow).fn.UI.fadeOutAndClose(  { "a": 0.7, "v": 3 }, 
                                                    null, 
                                                    null 
                                                  );
  
  $(LightWindowT.divWindowTrasparent).fn.UI.fadeOutAndClose(  { "a": 0.7, "v": 3 }, 
                                                              null, 
                                                              cbFn 
                                                           );
};

LightWindowT.hide = function ()
{
  $(LightWindowT.divWindow).fn.UI.close();
  $(LightWindowT.divWindowTrasparent).fn.UI.close();
  
  // Fire onload Gallery Event
  LightWindowT.onafterhide.fire();
};

LightWindowT.swapObject = function ( obj )
{ 
  var obj = $(obj);
  obj.style.display = ( obj.fn.css("width") == "auto" ) ? ("inline-block") : ("block");
  
  if ( LightWindowT.obj )
  {
    //LightWindowT.obj.parentNode.replaceChild( obj, LightWindowT.obj );
    LightWindowT.tdWindow.replaceChild( obj, LightWindowT.obj );
    this.obj = obj;
  }
  else
  {
    LightWindowT.obj = LightWindowT.tdWindow.appendChild( obj );
  }
  
  // Centramento per Mozilla
  LightWindowT.obj.style.marginLeft   = "auto";
  LightWindowT.obj.style.marginRight  = "auto";
};

LightWindowT.reposition = function ( )
{ 
  LightWindowT.onafterreposition.fire();
};
/*******************************************************************************
  [END LightWindowT STATIC]  
*******************************************************************************/
})();
/*************************************************************************[info]
  OBJECT:               XToolbar
  REQUIRED:             Framework eXtend (v2) (eXtend)
  DATA:                 02/03/2009
  COMPANY:              Onlime S.n.c.
 
  VERS:                 1.0
  LAST EDIT:            27/04/2009
  
  PURPOSE:              ...
  
  TODO:                 
    - ...
    
  LIMITI:  
    - ....
    
  NOTE:
    - ... 
*******************************************************************************/
(function() {
/*******************************************************************************
  [Object XToolbar]  
*******************************************************************************/
/** */
XToolbar = function( parameters )
{
  this.bar            = null;
  this.stepW          = null;
  this.stepH          = null;
  this.img            = null;
  this.arrEvent       = null; // Array di eventi. In questo modo posso attivarli o disattivarli in un colpo solo

  this.init(parameters);
}

/** */
XToolbar.prototype.init = function( parameters )
{
  this.bar = createElement( "div", parameters["id"] );   
  this.bar.setAttribute( "id"    , parameters["id"] );
  
  this.stepW          = parseInt( parameters["stepW"] || parameters["step"] || 0 ); // Retrocompatibilità 
  this.stepH          = parseInt( parameters["stepH"] || this.stepW );
  this.img            = parameters["img"];
  this.arrEvent       = [];
}

/** */
XToolbar.prototype.createToolButton= function( parameters )
{
  var stepW   = this.stepW;
  var stepH   = this.stepH;
  
  var offsetW;
  if ( parameters["offset"] )
  {
    offsetW = parseInt(parameters["offset"]); // Retrocompatibilità
  }
  else if ( parameters["offsetW"] )
  {
    offsetW = parseInt(parameters["offsetW"]);
  }
  else
  {
    offsetW = 0;
  }
  
  var offsetH = (parameters["offsetH"]) ? (parseInt(parameters["offsetH"])) :(0);
  var title   = parameters["title"] || "";
  var idName  = parameters["id"] || "";
  var toolImg = this.img;
  
  var divButton   = createElement("div", idName);
  divButton.setAttribute("id", idName);
  divButton.style.width  = stepW + "px";
  divButton.style.height = stepH + "px";
  
  var linkButton  = createElement("a", idName+"_link");
  linkButton.setAttribute("id", idName+"_link");
  
  linkButton.setAttribute("href", "javascript:;");
  linkButton.setAttribute("title", title);
  linkButton.style.backgroundImage    = "url(" + toolImg + ")";
  linkButton.style.backgroundPosition = "-" +( offsetW*stepW )+ "px " +( offsetH*stepH )+ "px";
  linkButton.style.backgroundRepeat   = "no-repeat";
  linkButton.style.width              = stepW + "px";
  linkButton.style.height             = stepH + "px";
  linkButton.style.display            = "block";
 
  divButton.appendChild( linkButton );
  
  var idState;
  var controlled;
  for ( var i=0; i < parameters["action"].length; i++ )
  {
    controlled  = parameters["action"][i]["controlled"] || true;
    argument    = parameters["action"][i]["param"] || null;
    
    idState = $E.add (linkButton, parameters["action"][i]["event"], parameters["action"][i]["fn"], false, argument);

    if ( ( idState != false) && controlled )
    {
      this.arrEvent[this.arrEvent.length] = idState;
    }
  }

  this.bar.appendChild( divButton );
  return divButton;
}

/** */
XToolbar.prototype.createSpecialToolButton = function( parameters )
{
  var stepW   = this.stepW;
  var stepH   = this.stepH;
  
  var offsetW;
  if ( parameters["offset"] )
  {
    offsetW = parseInt(parameters["offset"]); // Retrocompatibilità
  }
  else if ( parameters["offsetW"] )
  {
    offsetW = parseInt(parameters["offsetW"]);
  }
  else
  {
    offsetW = 0;
  }
  
  var offsetH       = (parameters["offsetH"]) ? (parseInt(parameters["offsetH"])) :(0);
  var title         = parameters["title"] || "";
  var idName        = parameters["id"] || "";
  var toolImg       = this.img;
  var offsetEffects = parameters["offsetEffects"] || {};
  
  var divButton   = createElement("div", idName);
  divButton.setAttribute("id", idName);
  divButton.style.width  = stepW + "px";
  divButton.style.height = stepH + "px";
  
  var linkButton  = createElement("a", idName+"_link");
  linkButton.setAttribute("id", idName+"_link");
  
  linkButton.setAttribute("href", "javascript:;");
  linkButton.setAttribute("title", title);
  linkButton.style.backgroundImage    = "url(" + toolImg + ")";
  linkButton.style.backgroundPosition = "-" +( offsetW*stepW )+ "px " +( offsetH*stepH )+ "px";
  linkButton.style.backgroundRepeat   = "no-repeat";
  linkButton.style.width              = stepW + "px";
  linkButton.style.height             = stepH + "px";
  linkButton.style.display            = "block";
 
  // Closure
  var objXToolbar = this;
  
  var opt = {
    "offsetEffects" : offsetEffects,
    "objXToolbar"   : objXToolbar,
    "offsetH"       : offsetH,
    "offsetW"       : offsetW,
    "stepW"         : stepW,
    "stepH"         : stepH };
    
  //linkButton.specialToolButton = new SpecialToolButton ( linkButton, opt );
  linkButton = new SpecialToolButton ( linkButton, opt );
  
  divButton.appendChild( linkButton );
  
  if ( parameters["action"] )
  {
    var idState;
    var controlled;
    for ( var i=0; i < parameters["action"].length; i++ )
    {
      controlled  = parameters["action"][i]["controlled"] || true;
      argument    = parameters["action"][i]["param"] || null;
      
      idState = $E.add (linkButton, parameters["action"][i]["event"], parameters["action"][i]["fn"], false, argument);
  
      if ( ( idState != false) && controlled )
      {
        this.arrEvent[this.arrEvent.length] = idState;
      }
    }
  }

  this.bar.appendChild( divButton );
  return divButton;
}

/** */
XToolbar.prototype.create = function()
{
  return this.bar;
}
/*******************************************************************************
  [END Object XToolbar]  
*******************************************************************************/
/*******************************************************************************
  [Object SpecialToolButton]
  
  ! Note : oggetto da portare fuori dal concetto di toolbar   
*******************************************************************************/
SpecialToolButton = function ( obj, parameters )
{
  if (!obj) return;
  
  this.offsetH                  = null;
  this.offsetW                  = null;
  this.stepW                    = null;
  this.stepH                    = null;
  this.domObj                   = null;
  this.offsetEffects            = null;
  this.active                   = null;
  
  SpecialToolButton.prototype.init.apply( this, [obj, parameters] );
  
  return this.domObj;
};

SpecialToolButton.prototype.init = function ( obj, parameters )
{
  parameters = parameters || {};
  
  this.offsetH                  = parameters["offsetH"];
  this.offsetW                  = parameters["offsetW"];
  this.stepW                    = parameters["stepW"];
  this.stepH                    = parameters["stepH"];
  this.offsetEffects            = parameters["offsetEffects"];
  this.domObj                   = obj; //$(obj);
  this.active                   = false;
  this.domObj.specialToolButton = this;
  
  var idxListenerMouseOver      = null;
  var idxListenerMouseOut       = null;
  var idxListenerClick          = null;
  
  // Attach effect event
  if ( this.offsetEffects["offsetOnMouseOver"] )
  {
    var fnHover = function (){ 
      this.specialToolButton.setOffsetH( this.specialToolButton.offsetEffects["offsetOnMouseOver"] ); 
    };
    idxListenerMouseOver =  $E.add ( this.domObj, "mouseover", fnHover, false );
  }
  
  if ( this.offsetEffects["offsetOnMouseOut"] )
  { 
    var fnOut = function (){ 
      this.specialToolButton.setOffsetH( this.specialToolButton.offsetEffects["offsetOnMouseOut"] ); 
    };
    idxListenerMouseOut = $E.add ( this.domObj, "mouseout", fnOut, false );
  }
  else
  {
    var fnOut = function (){ 
      this.specialToolButton.setOffsetH( 0 ); 
    };
    idxListenerMouseOut = $E.add ( this.domObj, "mouseout", fnOut, false );
  }
  
  if ( this.offsetEffects["offsetOnClick"] )
  { 
    var fnClick = function (){
      if ( !this.active )
      { 
        $E.deactiveIdx( idxListenerMouseOut );
        $E.deactiveIdx( idxListenerMouseOver );
        this.active = true;
        this.specialToolButton.setOffsetH( this.specialToolButton.offsetEffects["offsetOnClick"] );
      }
      else
      {
        $E.activeIdx( idxListenerMouseOut );
        $E.activeIdx( idxListenerMouseOver );
        this.active = false;
        this.specialToolButton.setOffsetH( 0 );
      }   
    };
    idxListenerClick = $E.add ( this.domObj, "click", fnClick, false );
  }
  
  return true;
};

SpecialToolButton.prototype.setOffsetH = function ( offsetH )
{
  this.offsetH = offsetH;
  this.domObj.style.backgroundPosition = "-" +( this.offsetW * this.stepW )+ "px -" +( this.offsetH * this.stepH )+ "px";
  return true;;
};

SpecialToolButton.prototype.setOffsetW = function ( offsetW )
{
  this.offsetW = offsetW;
  this.domObj.style.backgroundPosition = "-" +( this.offsetW * this.stepW )+ "px -" +( this.offsetH * this.stepH )+ "px";
  return true;
};

SpecialToolButton.prototype.setOffset = function ( offsetW, offsetH )
{
  this.offsetH = offsetH;
  this.offsetW = offsetW;
  this.domObj.style.backgroundPosition = "-" +( this.offsetW * this.stepW )+ "px -" +( this.offsetH * this.stepH )+ "px";
  return true;
};

SpecialToolButton.prototype.getOffsetH = function ()
{
  return this.offsetH;
};

SpecialToolButton.prototype.getOffsetW = function ()
{
  return this.offsetW;
};
/*******************************************************************************
  [END Object SpecialToolButton]  
*******************************************************************************/
})();
/*************************************************************************[info]
  OBJECT:               $C - filter 
  REQUIRED:             Framework eXtend (v2) (eXtend)
  DATA:                 06/11/2009
  COMPANY:              Onlime S.n.c.
 
  VERS:                 1.0
  LAST EDIT:            06/11/2009
  
  TODO:                 
    - ...           
    
  LIMITI:  
    - ...
*******************************************************************************/

$C = function( obj, kind, parameters, error )
{
  switch (kind)
  {
    case "stringFilter" : filter.stringFilter.apply(null, [ $(obj), parameters, error ] );
                          break;
    case "numberFilter" : filter.numberFilter.apply(null, [ $(obj), parameters, error ] );
                          break;
    case "dataFilter"   : filter.dataFilter.apply(null, [ { "giorno" : $(obj["giorno"]) , "mese" : $(obj["mese"]) , "anno" : $(obj["anno"]) }, parameters, error ] );
                          break;
    case "timeFilter"   : filter.timeFilter.apply(null, [ { "ore" : $(obj["ore"]) , "minuti" : $(obj["minuti"]) }, parameters ], error );
                          break;
    case "checkFilter"  : filter.checkFilter.apply(null, [ $(obj), parameters, error ] );
                          break;
                                                                  
    defaut              : break;
  }

};

filter = {};

filter.stringFilter = function( obj, parameters, error )
{
  // Imposto le propriet
  if (!parameters) parameters = {};
  obj.optional    = parameters["optional"]  || false;
  obj.minLen      = parameters["minLen"]    || 0;
  obj.htmlControl = parameters["html"] || false;
  obj.trimmed     = parameters["trim"] || true;
  
  if (!error) error = {};
  obj.response = {
                    "fieldname" :  ( error["fieldname"] || obj.id ) , 
                    "obj"       :  ( error["obj"] || obj ),
                    "container" :  ( error["container"] || obj ),
                    "response"  :  ( error["response"] || obj )
                 };
  
  // Definisco la funzione di controllo ( non pu pi chiamarsi 'fn' collide con fn della eXtendf)
  check = function(regEx)
          {
            var maxLen  = this.getAttribute("maxlength") || null;   // Lunghezza massima ( potrei cmq passarlo come parametro. Se non c' uso l'attributo se non c' non lo considero )
            var minLen  = this.minLen;                      // Lunghezza minima
            var opt     = this.optional;                    // Opzionalit
            
            var str_controlled = (this.htmlControl)? strip_tags(this.value) : this.value;   // Tolgo l'html            
            str_controlled = (this.trimmed)? trim(str_controlled) : str_controlled;         // Trimmo la stringa
            
            // Filtro l'input
            if ( str_controlled.length == 0 )
            {
              if ( !opt )
              {
                // Errore. Campo obbligatorio
                this.response["errno"] = "1";
                return this.response;
              }
            }
            else
            {
              if ( str_controlled.length < minLen )
              {
                // Errore. Stringa troppo corta.
                this.response["errno"] = "2";
                return this.response;
              }
              else
              { 
                if ( ( maxLen != null ) && ( str_controlled.length > maxLen ) )
                {
                  // Errore. Stringa troppo lunga.
                  this.response["errno"] = "3";
                  return this.response;
                }

                if ( regEx && (this.value.match(regEx) == null ) )
                {
                  // Errore . Formato non corretto
                  this.response["errno"] = "4";
                  return this.response;
                }
                
              }
            }              
            
            // Test passato. Input corretto.
            delete this.response["errno"];
            return this.response;
            
          }.bind( obj, parameters["regex"] );
  
  obj.chkFn = check; 
  
}; 

filter.numberFilter = function( obj, parameters, error )
{
  // Imposto le propriet
  if (!parameters) parameters = {};
  obj.optional = parameters["optional"] || false;
  obj.minValue = (parameters["minValue"] == null) ? null : parameters["minValue"];
  obj.maxValue = (parameters["maxValue"] == null) ? null : parameters["maxValue"];
  
  var cfn = parameters["check"] || is_numeric;
  
  if (!error) error = {};
  obj.response = {
                    "fieldname" :  ( error["fieldname"] || obj.id ) , 
                    "obj"       :  ( error["obj"] || obj ),
                    "container" :  ( error["container"] || obj ),
                    "response"  :  ( error["response"] || obj )
                 };
  
  // Definisco la funzione di controllo ( non pu pi chiamarsi 'fn' collide con fn della eXtendf)
  check = function(checkfn)
          {              
            var opt     = this.optional;                    // Opzionalit
            var minVal  = this.minValue;                    // Valore minimo permesso
            var maxVal  = this.maxValue;                    // Valore massimo permesso
            
            // Filtro l'input
            if ( this.value.length == 0 )
            {
              if ( !opt )
              {
                // Errore. Campo obbligatorio
                this.response["errno"] = "1";
                return this.response;
              }
            }
            else
            {
              if ( ( minVal !=null ) && (this.value < minVal) )
              {
                // Errore. Valore troppo basso
                this.response["errno"] = "5";
                return this.response;
              }
              else
              {
                if ( ( maxVal != null ) && (this.value > maxVal) )
                {
                  // Errore. Valore troppo alto
                  this.response["errno"] = "6";
                  return this.response;
                }
                else
                {
                  if ( checkfn && !checkfn(this.value) )
                  {
                    // Errore . Formato non corretto
                    this.response["errno"] = "4";
                    return this.response;
                  }
                }       
              }              
            }
            // Test passato. Input corretto.
            delete this.response["errno"];
            return this.response;
            
          }.bind( obj, cfn );
  
  obj.chkFn = check; 
  
}; 

filter.dataFilter = function( arr_obj, parameters, error )
{
  // Imposto le propriet
  if (!parameters) parameters = {};
  arr_obj["giorno"].optional = arr_obj["mese"].optional = arr_obj["anno"].optional = parameters["optional"] || false;
  
  if (!error) error = {};
  arr_obj["giorno"].response = {
                                  "fieldname" :  ( error["fieldname"] || arr_obj["giorno"].id ) , 
                                  "obj"       :  ( error["obj"] || arr_obj["giorno"] ),
                                  "container" :  ( error["container"] || arr_obj["giorno"] ),
                                  "response"  :  ( error["response"] || arr_obj["giorno"] )
                               };
  
  check= function(regEx)
        {
          var opt   = this["giorno"].optional;
          
          if ( ( this["giorno"].value == "" ) && ( this["mese"].value == "" ) && ( this["anno"].value == "" ) )
          {
            if (opt)
            {
              delete this["giorno"].response["errno"];
              return this["giorno"].response;
            }
            else
            {
              // Errore. Campo obbligatorio
              this["giorno"].response["errno"] = "1";
              return this["giorno"].response;
            }
            
          }
          else
          {
            
            var curr_date = this["giorno"].value + "-" + this["mese"].value + "-" + this["anno"].value;
          	var espressione = new RegExp("^[0-3]{0,1}[0-9]-(0|1){0,1}[0-9]-(19|20)[0-9]{2}$");
          	if ( !espressione.test(curr_date) )
          	{
          	  this["giorno"].response["errno"] = "9";
              return this["giorno"].response;
          	}
            else
            {
          		anno    = parseInt(this["anno"].value);
          		mese    = parseInt(this["mese"].value);
          		giorno  = parseInt(this["giorno"].value);
          		
          		var data  = new Date(anno, mese-1, giorno);
          		if  ( ( data.getFullYear() == anno ) && ( data.getMonth() + 1 == mese ) && ( data.getDate() == giorno ) )
              {
          			delete this["giorno"].response["errno"];
                return this["giorno"].response;
          		}
              else
              {
          			this["giorno"].response["errno"] = "9";
                return this["giorno"].response;
          		}
          	}
            
          }

          // Test passato. Input corretto.
          delete this["giorno"].response["errno"];
          return this["giorno"].response;
          
        }.bind( arr_obj );
               
  arr_obj["giorno"].chkFn = check;    
};

filter.timeFilter = function( arr_obj, parameters, error )
{
  // Imposto le propriet
  if (!parameters) parameters = {};
  arr_obj["ore"].optional = arr_obj["minuti"].optional = parameters["optional"] || false;
  
  // arr_obj["secondi"].optional  // Posso introdurre i secondi solo se passati come argomento
  if (!error) error = {};
  arr_obj["ore"].response = {
                                  "fieldname" :  ( error["fieldname"] || arr_obj["ore"].id ) , 
                                  "obj"       :  ( error["obj"] || arr_obj["ore"] ),
                                  "container" :  ( error["container"] || arr_obj["ore"] ),
                                  "response"  :  ( error["response"] || arr_obj["ore"] )
                               };
  
  check= function(regEx)
        {
          var opt   = this["ore"].optional;
          
          if ( ( this["ore"].value == "" ) && ( this["minuti"].value == "" ) )
          {
            if (opt)
            {
              return true;
            }
            else
            {
              // Errore. Campo obbligatorio
              this["ore"].response["errno"] = "1";
              return this["ore"].response;
            }
            
          }
          else
          {
            // Proseguo i controlli
            var curr_time = this["ore"].value + ":" + this["minuti"].value + ":00";
            var pattern = new RegExp( "^(([0-1]?[0-9])|([2][0-3])):([0-5]?[0-9])(:([0-5]?[0-9]))$");
            
            if ( curr_time.match(pattern) == null )
            {
              this["ore"].response["errno"] = "4";
              return this["ore"].response;
            }

          }

          // Test passato. Input corretto.
          delete this["ore"].response["errno"];
          return this["ore"].response;
          
        }.bind( arr_obj );
               
  arr_obj["ore"].chkFn = check;
};


filter.checkFilter = function( obj, parameters, error )
{
  // Imposto le propriet
  if (!parameters) parameters = {};
  obj.optional    = parameters["optional"]  || false;
  
  if (!error) error = {};
  obj.response = {
                    "fieldname" :  ( error["fieldname"] || obj.id ) , 
                    "obj"       :  ( error["obj"] || obj ),
                    "container" :  ( error["container"] || obj ),
                    "response"  :  ( error["response"] || obj )
                 };
  
  check = function()
          {
            var opt = this.optional; // Opzionalit
            
            // Filtro l'input
            if ( !this.checked )
            {
              if ( !opt )
              {
                // Errore. Campo obbligatorio
                this.response["errno"] = "1";
                return this.response;
              }
            }
            
            // Test passato. Input corretto.
            delete this.response["errno"];
            return this.response;
            
          }.bind( obj );
  
  obj.chkFn = check; 
  
}; 


// Funzione per togliere i tag - DA POSIZIONARE IN EXTEND
function strip_tags(str){
 return str.replace(/<\/?[^>]+>/gi, '');
}


/*************************************************************************[info]
  OBJECT:               XEditor
  REQUIRED:             Framework eXtend (v2) (eXtend)
  DATA:                 06/11/2009
  COMPANY:              Onlime S.n.c.
 
  VERS:                 1.0
  LAST EDIT:            06/11/2009
  
  PURPOSE:              JavaScript per editor HTML
  
  TODO:                 
    - ...
    
  LIMITI:  
    - ....
    
  NOTE:
  
    tool    -> 'nome_text'_toolbar ( per i css)
    iframe  -> 'nome_text'_iframe ( per i css)
    
    Così i css rimangono esterni
    
    Per l'hidden che contiene il valore httml dell'iframe
    usiamo lo stesso nome della text (i css possono differenziare il nome
    di una text e di un hidden).
    Al send dobbiamo riportare il valore dell'iframe nell'hidden e poi inviamo
     l'hidden
    
    Per la validazione possiamo usare uno stringFilter su hidden  
*******************************************************************************/
XEditor = function( parameters )
{
  this.obj      = null;
  this.toolPath = null;
  this.css      = null;
  this.width    = null;
  this.height   = null;
  this.iframe   = null;

  this.init( parameters );
};

XEditor.prototype.init = function( parameters )
{
  // Imposto i dati dell'oggetto
  this.obj      = $( parameters["obj"] );
  this.toolPath = parameters["toolbar"] || PATH_XEDITOR + "img/toolbar.png";
  this.css      = parameters["css"]     || "";
  this.width    = parameters["width"]   || this.obj.style.width;
  this.height   = parameters["height"]  || this.obj.style.height;
  
  // Tolgo la stringa px se presente ( e lo converto in numero).
  this.width    = parseFloat(this.width);
  this.height   = parseFloat(this.height);
  
  // Imposto le variabili locali
  var obj       = this.obj;
  var root_img  = this.toolPath;
  
  // Creo iframe per html mode     
  var iframe = createElement( "iframe", obj.id + "_iframe" );   
  iframe.setAttribute("id"            , obj.id + "_iframe"); 
  iframe.setAttribute("frameborder"   , "0");
  iframe.mode = true;
  
  // Imposto gli stili per l'iframe
  iframe.style.border = "1px solid gray";
  iframe.style.width  = this.width + "px";
  iframe.style.height = this.height + "px";
  
  // Inserisco l'iframe ( IE compatibile )
  obj.parentNode.replaceChild(iframe,obj);
  
  iFrameID = obj.id + "_iframe";
  if(self.frames[iFrameID].name != iFrameID)
  { 
    self.frames[iFrameID].name = iFrameID;
  }
  
  // Definisco gli stili
  var css = "";
  if ( this.css == "" )
  {   
    css = "<style>" + loadSyncFile( PATH_XEDITOR_RELATIVE + "css/cssXEditor.css", false) + "</style>";
  }
  else
  {
    css = "<style>" + loadSyncFile( this.css, false) + "</style>";
  }
  
  // Attivo la modalità di scrittura su iframe
  try
  {
    iframe.contentDocument.open();
    iframe.contentDocument.write(css + obj.value);
    iframe.contentDocument.close();          
    iframe.contentDocument.designMode = 'on';
  }
  catch(e)
  {
    frames[iframe.id].document.open();
    frames[iframe.id].document.write(css + obj.value);
    frames[iframe.id].document.close();
    frames[iframe.id].document.designMode = 'On';
  }
    
  // Creo l'oggetto toolbar
  var tool = new XToolbar ( { "id" : obj.id + "_toolbar", "step" : 16 , "img" : this.toolPath} );
  
  // Creo i componenti della toolbar
  
  actionButton = function (e, idx, arg)
                  {
                    $E.preventDefault(e);
                    try
                    {
                      iframe.contentDocument.execCommand(arg["command"], false, null);
                      iframe.contentWindow.focus();
                    }
                    catch(exc)
                    {
                      iframe.contentWindow.focus(); 
                      iframe.document.execCommand(arg["command"], false, null);
                    } 
                    
                    controlState();
                      
                  }
                      
  // creo hover che mette il bordo solo se lo stato è true.
  actionOver  = function(e, idx){
                  $(this).fn.css( { "border" : "1px solid gray"} );
                }
  actionOut   = function(e, idx){
                  $(this).fn.css( { "border" : "1px solid transparent"} );
                }

  addCss = function(node)
            {
              node.setAttribute("style","float:left");
              node.style.border     = "1px solid transparent";
              node.style.marginTop  = "3px";
              node.style.marginLeft = "5px";
              node.style.styleFloat = "left";
              node.style.padding    = "1px";
              
              var lnk = node.childNodes[0];
              lnk.style.padding      = "0";
              lnk.style.margin       = "0";
              lnk.style.fontSize     = "0";
              lnk.style.lineHeight   = "0";
              
              $E.add (node, "mouseover", actionOver , false, null);
              $E.add (node, "mouseout", actionOut , false, null);
            }
  
  var tmp;

  // Set per lo stile di scrittura
  tmp = tool.createToolButton( { "offset" : 2 ,"id" : obj.id + "_toolbar_bold", "title" : "Grassetto" , "action" : [{"event" : "click" , "fn" : actionButton, "param" : { "command" : "bold" }  }] } );
  addCss(tmp);
  tmp = tool.createToolButton( { "offset" : 3 ,"id" : obj.id + "_toolbar_italic", "title" : "Corsivo" , "action" : [{"event" : "click" , "fn" : actionButton, "param" : { "command" : "italic" }  }] } );
  addCss(tmp);
  tmp = tool.createToolButton( { "offset" : 4 ,"id" : obj.id + "_toolbar_underline", "title" : "Sottolineato" , "action" : [{"event" : "click" , "fn" : actionButton, "param" : { "command" : "underline" }  }] } );
  addCss(tmp);
  // Qui ci starebbe bene un divisorio
  
  // Set per l'allineamento
  tmp = tool.createToolButton( { "offset" : 12 ,"id" : obj.id + "_toolbar_justifyleft", "title" : "Allinea a sinistra" ,"action" : [{"event" : "click" , "fn" : actionButton, "param" : { "command" : "justifyleft" }  }] } );
  addCss(tmp);
  tmp = tool.createToolButton( { "offset" : 13 ,"id" : obj.id + "_toolbar_justifycenter", "title" : "Allinea al centro" ,"action" : [{"event" : "click" , "fn" : actionButton, "param" : { "command" : "justifycenter" }  }] } );
  addCss(tmp);
  tmp = tool.createToolButton( { "offset" : 14 ,"id" : obj.id + "_toolbar_justifyright", "title" : "Allinea a destra" ,"action" : [{"event" : "click" , "fn" : actionButton, "param" : { "command" : "justifyright" }  }] } );
  addCss(tmp);
  tmp = tool.createToolButton( { "offset" : 20 ,"id" : obj.id + "_toolbar_justifyfull", "title" : "Giustificato" ,"action" : [{"event" : "click" , "fn" : actionButton, "param" : { "command" : "justifyfull" }  }] } );
  addCss(tmp);
  
  // Set per le liste
  tmp = tool.createToolButton( { "offset" : 10 ,"id" : obj.id + "_toolbar_insertunorderedlist", "title" : "Lista", "action" : [{"event" : "click" , "fn" : actionButton, "param" : { "command" : "insertunorderedlist" }  }] } );
  addCss(tmp);
  tmp = tool.createToolButton( { "offset" : 11 ,"id" : obj.id + "_toolbar_insertorderedlist", "title" : "Lista ordinata", "action" : [{"event" : "click" , "fn" : actionButton, "param" : { "command" : "insertorderedlist" }  }] } );
  addCss(tmp);
  
  // Inserimento link   
  actionLinkButton = function (e, idx)
                    {
                      $E.preventDefault(e);
                      
                      // Non si comporta come gli altri pulsanti. Do l'effetto di hover
                      $(obj.id + "_toolbar_createlink").fn.css( { "background" : "lightgrey"} );
                      
                      address = prompt("Inserisci l'indirizzo del link", "http://");
                      if ( address != null )
                      {
                        try
                        {
                          iframe.contentDocument.execCommand("createlink", false, address); 
                          iframe.contentWindow.focus();
                        }
                        catch(exc)
                        {
                          iframe.contentWindow.focus(); 
                          iframe.document.execCommand("createlink", false, address);
                        }
                      }
                      else
                      {
                        iframe.contentWindow.focus();
                      }
                      // Finita l'azione riporto il pulsante alla normalità                       
                      $(obj.id + "_toolbar_createlink").fn.css( { "background" : "transparent"} );
                        
                    }
  
  tmp = tool.createToolButton( { "offset" : 35 ,"id" : obj.id + "_toolbar_createlink", "title" : "Link", "action" : [{"event" : "click" , "fn" : actionLinkButton }] } );
  addCss(tmp);
  
  /*
  // Selezione modalità di visione ( html - wysiwyg) - DISABILITATO ( se nel invio rimane in HTML mode il codice passato viene trasformato in entità. Prevedere o un blocco sull'invio o uno swap automatico all'interno di xForm prima di prendere il valore. Anche nel getValue si può mettere senza toccare xForm )
  modeButton = function (e, idx)
                {
                  if ( !iframe.document )
                  {
                    if (iframe.mode)  // Da wysiwyg a html
                    {
                      // Da HTML a TEXT
                      var html = document.createTextNode( iframe.contentWindow.document.body.innerHTML );
                      iframe.contentWindow.document.body.innerHTML = "";
                      iframe.contentWindow.document.body.appendChild( html );
                      this.setAttribute("title", "Passa alla modalità editor");
                      iframe.mode = false;
                    }
                    else              // Da html a wysiwyg 
                    {
                      var html = iframe.contentWindow.document.createRange();
                      html.selectNodeContents( iframe.contentWindow.document.body );
                      iframe.contentWindow.document.body.innerHTML = html.toString();
                      this.setAttribute("title", "Passa alla modalità HTML");
                      iframe.mode = true;
                    }
                  }
                  else
                  {
                    if (iframe.mode)  // Da wysiwyg a html
                    {
                      iHTML = frames[iframe.id].document.body.innerHTML;
                      frames[iframe.id].document.body.innerText = iHTML;
                      this.setAttribute("title", "Passa alla modalità editor");
                      iframe.mode = false;
                    }
                    else              // Da html a wysiwyg 
                    {
                      iText = frames[iframe.id].document.body.innerText;
                      frames[iframe.id].document.body.innerHTML = iText;
                      this.setAttribute("title", "Passa alla modalità HTML");
                      iframe.mode = true;
                    }
                  }
                }
  
  tmp = tool.createToolButton( { "offset" : 34 ,"id" : obj.id + "_toolbar_mode", "title" : "Passa alla modalità HTML", "action" : [{"event" : "click" , "fn" : modeButton }] } );
  addCss(tmp);
  tmp.setAttribute("style","float:right");
  tmp.style.styleFloat  = "right";
  tmp.style.border      = "1px solid transparent";
  tmp.style.marginTop   = "3px";
  tmp.style.marginRight = "5px";
  tmp.style.padding     = "1px";
  
  */
  
  // Funzione controllo dello stato di un pulsante
  controlButton = function (action)
                  {
                    try
                    {
                      var cn = iframe.contentDocument.queryCommandState(action); 
                    }
                    catch(exc)
                    {
                      var cn = iframe.document.selection.createRange().queryCommandState(action);
                    }
                    
                    if (cn)
                    {
                      $(obj.id + "_toolbar_" + action).fn.css( { "background" : "lightgrey"} );
                    }
                    else
                    {
                      $(obj.id + "_toolbar_" + action).fn.css( { "background" : "transparent"} );
                    }
                  }
  
  // Funzione di controllo pulsanti ( se poi sarà possibile abilitare alcuni pulsanti, questa funzione dovrà prevederlo  )
  controlState = function ()
                  {
                    var arrButton = [ "bold", "italic", "underline", "justifyleft", "justifycenter",
                                      "justifyright", "justifyfull", "insertunorderedlist",
                                      "insertorderedlist"];
                    
                    for (var i=0; i<arrButton.length; i++ )
                    {
                      controlButton( arrButton[i] );
                    }
                    
                  }
      
  var toolObj = tool.create();    
  
  // Aggiungo lo stile alla toolbar ( recuperando anche la lunghezza della text )
  toolObj.style.background   = "#F0F0F0";
  toolObj.style.width        = ( this.width + 2 ) + "px";  // considerare anche i bordi di pixel e togliere il px e poi rimetterlo.
  toolObj.style.height       = "26px";
  toolObj.style.overflow     = "hidden";
  toolObj.style.marginBottom = "2px";
  
  iframe.parentNode.insertBefore(toolObj,iframe);

  // Aggiungo gli eventi di gestione pulsanti da iframe per FF  ( ma forse non servono! funziona cmq! )
  //$E.add (iframe.contentDocument, "keyup", controlState , false, null);
  //$E.add (iframe.contentDocument, "click", controlState , false, null);
  
  // Aggiungo gli eventi di gestione pulsanti da iframe per IE  
  $E.add (iframe.contentWindow.document, "keyup", controlState , false, null);
  $E.add (iframe.contentWindow.document, "click", controlState , false, null);
  
  
  // Creo il nodo hidden che conterrà il valore dell'editor.
  var hidden = createElement( "input", obj.id + "_value" );   
  hidden.setAttribute("id"           , obj.id + "_value");
  hidden.setAttribute("type"         , "hidden");
  hidden.XEditor = this;
   
  iframe.parentNode.insertBefore(hidden,toolObj);
  this.iframe = iframe;
  
  // Inizializzo gli stati
  controlState();
  
  // Nell'hidden che conterrà i valori inserisco una variabile che si riferisce all'istanza ( this )
  // di XEditor. In questo modo all'interno della funzione di submit possiamo capire se l'hidden è
  // legato ad un editor e recuperarne il valore con l'apposita funzione getValue() 
  
  // Inserisco la funzione di validazione sull'hidden. Lato codice pagina. Infatti so come si chiama l'hidden 
  // nome_value
  
  // Tramite gli ultimi due punti. Nella submit quando controllo gli hidden devo controllare se dipendono
  // da un iframe. nel caso effettuo il caricamento del contenuto dell'iframe e poi faccio scattare
  // la chkFn sul value ottenuto. Che mi controlla perfettamente cosa devo passare.

}

XEditor.prototype.getValue = function()
{ 
  // Recupero il contenuto dell'iframe
  str = getIframeValue(this.iframe);
  
  // Correzione comportamente IE
  str = str.replace(/<P>&nbsp;<\/P>/g, "<br>");
  str = str.replace(/&nbsp;/g, " ");
  
  // Trasformo ie in firefox compliant
  str = str.replace(/<P>/g, "");
  str = str.replace(/<\/P>/g, "<br>");
  
  str = str.replace(/<STRONG>/g, "<span style=\"font-weight: bold;\">");
  str = str.replace(/<\/STRONG>/g, "</span>");
  
  str = str.replace(/<EM>/g, "<span style=\"font-style: italic;\">");
  str = str.replace(/<\/EM>/g, "</span>");
  
  str = str.replace(/<U>/g, "<span style=\"text-decoration: underline;\">");
  str = str.replace(/<\/U>/g, "</span>");
  
  str = str.replace(/<UL>/g, "<ul>");
  str = str.replace(/<\/UL>/g, "</ul>");
  
  str = str.replace(/<LI>/g, "<li>");
  str = str.replace(/<\/LI>/g, "</li>");
  
  return str;
}

/*************************************************************************[info]
  OBJECT:               XFile
  REQUIRED:             Framework eXtend (v2) (eXtend)
  DATA:                 06/11/2009
  COMPANY:              Onlime S.n.c.
 
  VERS:                 1.0
  LAST EDIT:            06/11/2009
  
  PURPOSE:              JavaScript per file asincroni
  
  TODO:                 
    - ...
    
  LIMITI:  
    - ....
    
  NOTE:
  
    Come funziona la preview. Per far funzionare correttamente la preview è necessario
    lato php/html impostare il src dell'immagine con il valore del file caricato o
    dell'immagine di default in caso di nessun file caricato.
    
    Sarà poi l'elemento pname ( o meglio la sua esistenza a determinarne il comportamento ).
    Se esiste allora l'immagine src gli si riferisce ( path dell'immagine ) se non 
    esise allora l'immagine caricata sarà un default.
    
    Nel primo caso avendo l'immagine caricata mancherebbe il default che deve essere inserito
    lato javascript come argomento. Nel secondo caso abbiamo il default ma possiamo non consideralo
    e far finta di ricondurci al primo caso. Avremo che in qls caso verrà mostrato il path di default
    sia seguendo il link rimuovi file che l'annulla.
    
    Ne consegue che l'argomento "default" deve essere obbligatorio per lo script  
*******************************************************************************/
//(function() {
XFile = function( parameters, error )
{
  this.file     = $( parameters["file"] );
  this.pname    = $( parameters["pname"] );
  this.preview  = $( parameters["preview"] );
  this.pnamelen = parameters["pnamelen"] || null;
  this.action   = parameters["action"];
  this.def      = parameters["default"] || "";
  this.opt      = parameters["optional"];

  this.init( error );
};

XFile.prototype.init = function( errMessage )
{
  var file    = this.file;
  var pname   = this.pname;
  var pnamelen= this.pnamelen;
  var preview = this.preview;
  var parent  = file.parentNode;
  
  // Recupero la form padre e il suo gestore di errori che uso all'interno del
  // codice di XFile. Così leghiamo i due elementi. 
  var frmParent = file;
  while ( ( ( frmParent = frmParent.parentNode ) != null ) && ( frmParent.tagName.toUpperCase() != "FORM" ) );
  
  // Proprietà di file
  file.lock = false;
  
  // Preview
  if (preview)
  {
    // Memorizzo l'indirizzo del default preview
    preview.defaultPath   = this.def;
    
    // Creo l'indirizzo dell'immagine caricata
    if (pname)
    {
      preview.originalPath = preview.src;
      preview.src = preview.originalPath;
    }
    else
    {
      preview.originalPath = preview.defaultPath;
    }
  }
  
  // Pname - se non esiste devo creare l'elemento.
  if (pname == null)
  {
    pname = createElement( "span", file.id + "_pname" );
    pname.setAttribute("id", file.id + "_pname" );
  }
  
  // Form
  var form = createElement( "form", file.id + "_form", "multipart/form-data" );
  form.setAttribute("id"      , file.id + "_form");
  form.setAttribute("target"  , file.id + "_iframe");
  form.setAttribute("action"  , this.action);
  form.setAttribute("method"  , "POST");
  form.setAttribute("display" , "inline");

  parent.replaceChild(form,file);   // Aggiungo la form al posto del file

  form.appendChild(file);         // Aggiungo il file alla form
  form.appendChild(pname);        // Aggiungo il nodo con il nome alla form
  
  // Link di rimozione
  var text_rimuovi  = document.createTextNode("Rimuovi");
  var rimuovi       = createElement( "a", file.id + "_rimuovi" );
  rimuovi.setAttribute("id"   , file.id + "_rimuovi");
  rimuovi.className = file.id + "_class";
  rimuovi.setAttribute("href" , "#");
  rimuovi.appendChild(text_rimuovi);
  
  form.appendChild(rimuovi);      // Aggiungo il link alla form
  
  // Link di annullamento
  var text_annulla  = document.createTextNode("Annulla");
  var annulla       = createElement( "a", file.id + "_annulla" );
  annulla.setAttribute("id", file.id + "_annulla");
  annulla.className = file.id + "_class";
  annulla.setAttribute("href", '#');    
  annulla.appendChild(text_annulla);

  form.appendChild(annulla);      // Aggiungo il link alla form
  
  // Iframe     
  var iframe = createElement( "iframe", file.id + "_iframe" );   
  iframe.setAttribute("id"          , file.id + "_iframe");
  iframe.setAttribute("name"        , file.id + "_iframe");    
  iframe.setAttribute("frameborder" ,"0");
  
  /* Devo sostituirli con il metodo css di eXtend */   

  iframe.style.height   = 0;                      // Rende l'iframe invisibile
  iframe.style.width    = 0;
  iframe.style.padding  = 0;
  iframe.style.margin   = 0;
  iframe.style.display  = "inline";

  form.appendChild(iframe);
  
  var iFrameID = file.id + "_iframe";
  if(self.frames[iFrameID].name != iFrameID)
  { 
    self.frames[iFrameID].name = iFrameID; 
  }
  
  // Hidden
  var hidden =  createElement( "input", file.id + "_name" );       
  hidden.setAttribute("id", file.id + "_name");
  hidden.setAttribute("type","hidden");
  hidden.opt = this.opt;

  form.parentNode.appendChild(hidden);              //  Aggiungo l' hidden alla form principale
  
  // Controllo i link
  if( pname.innerHTML == "" )
  {     
    file.fn.UI.open({ "displayMode" : "inline" });    // Mostro l'oggetto file
    $(rimuovi).fn.UI.close();                         // Nascondo il link
    $(annulla).fn.UI.close();                         // Nascondo il link
    
    file.old_file = "";                 // Imposto nome file originale
    hidden.value  = ""                  // Svuoto il contenuto dell'hidden
  }
  else
  {
    file.fn.UI.close();                                   // Nascondo l'oggetto file
    $(rimuovi).fn.UI.open({ "displayMode" : "inline" });  // Mostro il link
    $(annulla).fn.UI.close();                             // Nascondo annulla non essendoci state azioni
    file.old_file = pname.innerHTML;                      // Imposto nome file originale
    hidden.value  = pname.innerHTML;                      // Imposto nome file originale
    
    // Controllo la lunghezza del nome mostrato
    var pname_view = pname.innerHTML;
    if ( pnamelen != null)
    {
      if  ( pnamelen < pname_view.length )
      {
        pname_ext   = pname_view.substring( pname_view.lastIndexOf("."));
        pname_view  = pname_view.substring(0, ( pnamelen - pname_ext.length -1 ) );
      
        pname_view += ".." + pname_ext;         
      }
      
      //Non uso più l'innerHTML      
      removeAllChild(pname);
      pname.appendChild(document.createTextNode( pname_view ));
      
    }
    
  }
  
  var removeFile = function(e)
  {
    // Devo bloccare l'azione di default
    $E.preventDefault(e);
  
    file.fn.UI.open({ "displayMode" : "inline" });
    $(rimuovi).fn.UI.close();      
    $(annulla).fn.UI.open({ "displayMode" : "inline" });    // Qui dobbiamo controllare se l'originale nome era vuoto. Se no va mostrato      
    removeAllChild(pname);                                  // Se ci fosse più di un elmento li elimina tutti. 
    
    hidden.value = "";                                      // Svuoto l'hidden. Se hidden è vuoto significa cancellazione. Se è pieno ma non c'è il file allora non si modifica. Se è pieno ed esiste il file nel temp va sostituito
    file.value = "";                                         // Cancello il contenuto dell'input file
    
    if (preview)
    {

      var swapImg = function(e,idx)
        {
          $E.removeIdx (idx);
          preview.fn.UI.fadeIn( null );
        };
      $E.add (preview, "load", swapImg, false);
      
      var cbLoad = function()
                    { 
                      preview.src = preview.defaultPath;
                    }; 
        
      preview.fn.UI.fadeOut( { "v" : 20 }, cbLoad );
      //cbLoad();
    }
    
  };
  
  $E.add (rimuovi, "click", removeFile, false);
  
  var undoAction = function(e)
  {
    // Devo bloccare l'azione di default
    $E.preventDefault(e);
    
    if ( file.old_file == "" )
    {
      file.fn.UI.open({ "displayMode" : "inline" });          // Mostro il file
      $(rimuovi).fn.UI.open({ "displayMode" : "inline" });    // Nascondo il link
      $(annulla).fn.UI.close();                               // Nascondo il link            
      removeAllChild(pname);                                  // Elimino il contenuto dello span
      
      hidden.value   = "";                                // Azzero tutto. Infatti prima non erano presenti
      file.value = "";                                    // Cancello il contenuto dell'input file
    }
    else
    {
      file.fn.UI.close();                                           // Nascondo il file
      $(rimuovi).fn.UI.open({ "displayMode" : "inline" });          // Mostro il link di rimozione
      $(annulla).fn.UI.close();                                     // Nascondo il link x' non avrebbe senso. Tutto viene già riportato indietro
      removeAllChild(pname);                                        // Cancello il precedente contenuto dello span 
      
      pname.appendChild(document.createTextNode(file.old_file));    // Imposto dal nome file originale      
      hidden.value   = file.old_file;                               // Imposto dal nome file originale
      
      // Controllo la lunghezza del nome mostrato
      var pname_view = pname.innerHTML;
      if ( pnamelen != null)
      {
        if  ( pnamelen < pname_view.length )
        {
          pname_ext   = pname_view.substring( pname_view.lastIndexOf("."));
          pname_view  = pname_view.substring(0, ( pnamelen - pname_ext.length -1 ) );
        
          pname_view += ".." + pname_ext;         
        }
        
        //Non uso più l'innerHTML      
        removeAllChild(pname);
        pname.appendChild(document.createTextNode( pname_view ));
      }
    }
    
    if (preview)
    {

      var swapImg = function(e,idx)
        {
          $E.removeIdx (idx);
          preview.fn.UI.fadeIn( null );
        };
        
      $E.add (preview, "load", swapImg, false);
      
      var cbLoad = function()
                    { 
                      preview.src = preview.originalPath;
                    }; 
        
      preview.fn.UI.fadeOut( { "v" : 20 }, cbLoad );
      //cbLoad();
      
    }
  };
  
  $E.add (annulla, "click", undoAction, false);
  
  var sendFile = function(e)
  { 
    // Potrei oltre il lock disabilitare anche il tag file per visibilità utente. 
    // E riabilitarlo quando reimposto il lock a false.
    if (!file.lock)
    {    
      file.lock = true;
      form.submit();
    }
  };
  
  $E.add (file, "change", sendFile, false);
  
  var loadResult = function(e)
  {
    // Correzioni per IE6 ( non legge xml dentro gli iframes )
    var res = getIframeValue(iframe);
    
    // Controllo che ci sia una response ( es. al primo caricamento è vuoto, non è così per il reload con passaggio di un post vuoto)
    if ( (!res) || (res=="") ) 
    {
      file.lock = false;
      return;
    }
    
    res = res.replace(/\\\[/g, "<");
    res = res.replace(/\\\]/g, ">");
    
    var responseXml = parseStrToXml(res);
    
    var report  = retriveRcFromXml( "report", responseXml );
    var error   = retriveRcFromXml( "error", responseXml );
    
    if (report)
    {
      // Imposto l'interfaccia
      file.fn.UI.close();
      $(rimuovi).fn.UI.open({ "displayMode" : "inline" });
      $(annulla).fn.UI.open({ "displayMode" : "inline" });
      
      // Limito i caratteri visibili
      var pname_view = report[0]["nomefile"];
      if ( pnamelen != null)
      {
        if  ( pnamelen < pname_view.length )
        {
          pname_ext   = pname_view.substring( pname_view.lastIndexOf("."));
          pname_view  = pname_view.substring(0, ( pnamelen - pname_ext.length -1 ) );
        
          pname_view += ".." + pname_ext;         
        }
      }
      
      removeAllChild(pname);
      pname.appendChild(document.createTextNode( pname_view ));
      
      hidden.value  = report[0]["nomefile"];
      file.value     = ""; 
      
      // Qui gestiremo l'eventuale preview
      if (preview)
      {
        var swapImg = function(e, idx)
                      {
                        $E.removeIdx (idx);
                        preview.fn.UI.fadeIn( null );
                      };
        
        $E.add (preview, "load", swapImg, false);

        var cbLoad = function()
                      { 
                        preview.src = report[0]["path"] + report[0]["nomefile"];
                      }; 
        
        preview.fn.UI.fadeOut( { "v" : 20 }, cbLoad);
        //cbLoad();
      }
      
      // Se va a buon fine il caricamento, allora cancello le notifiche errate
      frmParent.errFn.clear(hidden.response);
      
    }
    else
    {
      if (error)
      {
        if ( isNaN(error[0]["mex"]) )
        {
          hidden.response["errno"] = "10";
        }
        else
        {
          hidden.response["errno"] = error[0]["mex"];
        }
        frmParent.errFn.fire(hidden.response);
        form.reset();
      }
      else
      {
        // Errore - sessione scaduta di solito
        frmParent.errFn.openNotify("Sessione scaduta");
        form.reset();
      }
    }
    
    file.lock = false;
  };
  
  $E.add (iframe, "load", loadResult, false);
  
  // Aggiungo la funzione di controllo
  
  if (!errMessage) errMessage = {};
  hidden.response =  {
                        "fieldname" :  ( errMessage["fieldname"] || iframe.id ) , 
                        "obj"       :  ( errMessage["obj"] || iframe ),
                        "container" :  ( errMessage["container"] || iframe ),
                        "response"  :  ( errMessage["response"] || iframe )
                     };
  
  var checkValue = function()
  {
    if (!hidden.opt)
    {
      if( hidden.value == "" )
      {
        hidden.response["errno"] = "1";
        return hidden.response;
      }
    }
    delete hidden.response["errno"];
    return hidden.response;
  };
  
  hidden.chkFn = checkValue;  // Forse è meglio legarli ai file?
  
}
//})();
/*************************************************************************[info]
  OBJECT:               XForm
  REQUIRED:             Framework eXtend (v2) (eXtend)
  DATA:                 06/11/2009
  COMPANY:              Onlime S.n.c.
 
  VERS:                 1.0
  LAST EDIT:            06/11/2009
  
  PURPOSE:              ...
  
  TODO:                 
    - ...
    
  LIMITI:  
    - ....
    
  NOTE:
  
    Diversamente da prima :
    Al load abilito i pulsanti del form. Se devono disabilitarli lo farò dopo
    la costruzione dell'oggetto a parte ( è  un caso meno frequente).
    Questo per il problema del refresh che in caso si disabiliti un input non
    lo riabilita se lo era di default.  
*******************************************************************************/

XForm = function( parameters )
{
  this.obj          = null;
  this.ajax         = null;     // Può essere true o false
  this.arg          = null;
  this.errFn        = null;
  this.sequentially = null;
  this.keyControl   = true;    

  this.init( parameters );
};


XForm.prototype.init = function( parameters )
{
  // Abbiamo anche un ulteriore funzione di controllo da impostare ed
  // usare nella send
  // Forse è anche il caso di far passare una funzione che viene lanciata per il loading.
  // se non è settata non fa nulla.
  
  this.arg          = parameters["arg"] || null;
  this.obj          = $( parameters["obj"] );
  this.controlFn    = parameters["fn"]  || null;
  this.loading      = parameters["loading"]  || null;
  this.errFn        = this.obj.errFn = parameters["errFn"] || XError;
  this.keyControl   = ( parameters["keyControl"] )? parameters["keyControl"] : true ;
     
  // definizione closure
  var instance    = this;
  
  if ( parameters["seq"] === false )
  {
    this.sequentially = false;
  }
  else
  {
    this.sequentially = true;
  }
  
  this.ajax       = (this.arg == null)? false : true;
  
  
  var normalFunction = function()
                    {
                      instance.send();
                    }
  
  var temporFunction = function()
                    {
                      var file = getElementsByAttribute( instance.obj, "input", "type", "file");
                      var traffic = false;
                      for ( var i=0; i < file.length ; i++ ) 
                      {
                        traffic = (file[i].lock)? true : traffic;
                      }

                      if ( traffic )
                      {
                        setTimeout( temporFunction, 200 );
                      }
                      else
                      {
                        instance.send();
                      }
                    }
  
  // Per explorer devo anche controllare il tasto di escape e di invio, infatti sono
  // collegate al submit e al send come azioni di default.
  
  var fnPreventSpecialKeyForm = function(e)
                    { 
                      var targ = $E.getTarget( e );
                      if( (targ) && (targ.tagName) && (targ.tagName.toLowerCase()=="textarea") ) return;                     
                      if( (e.keyCode == getKeyID( "Escape" )) || (e.keyCode == getKeyID( "Enter" )) )
                      {
                        $E.preventDefault( e );
                      }
                    };
                    
  if ( this.keyControl )
  {                 
    $E.add( this.obj, "keydown", fnPreventSpecialKeyForm, false);
  }
  
  // Per renderla più dinamica. Possiamo mettere le 2 righe in una funzione che le raggruppa e che sceglie
  // dinamicamente quale far partire. Così se aggiungiamo dei file a runtime li troviamo e la funzione si adatta!   
  // Andrebbe racchiusa nella var anche questa. Senza var si perde il riferimento all'istanza. 
  submitFunction = function(e)
  {
    $E.preventDefault(e);
    
    // utilizzo closure
    var file = getElementsByAttribute(instance.obj, "input", "type", "file");
    if ( file.length == 0 )
    {
      normalFunction();
    }
    else
    { 
      temporFunction();
    }
    
    // Se impostiamo un valore di ritorno per il send. sappiamo se riabilitare
    // o meno i pulsanti. 
    // Se il send è a buon fine non riabilito i pulsanti. 
    // - caso normale: cambio pagina e non mi interessa.
    // - caso ajax: la response riabilità i pulsanti. 
    // E' la protezione migliore
    
  }
  
  // Se è previsto l'uso anche deii reset devo considerarli anche qui
  var subm = getElementsByAttribute( this.obj, "input", "type", "submit" ); 
  for ( var i=0; i < subm.length ; i++ ) subm[i].disabled = false;
  
  $E.add ( this.obj, "submit", submitFunction, false, null );
  
}

XForm.prototype.send = function()
{
  var test = true;
  if (this.ajax) var AjCall = $A(this.arg);
  
  var els = this.obj.elements;
  
  if ( this.sequentially )
  {
    // Devo ciclare per tutti gli elementi e pulirli.
    for (var i = 0; i<els.length; i++) 
    { 
		  el = els[i];
		  
		  if ( el.XEditor ) el.value = el.XEditor.getValue();
		  
		  if ( el.chkFn )
		  {
		    this.errFn.clear( el.chkFn() );
		  }
		}  
  } 
  
  for (var i = 0; i<els.length; i++) 
  { 
		el = els[i];
		
		// se il valore è da non passare salto all'elemento successivo
		var isToExclude = el.getAttribute("exclude");
		if( (isToExclude) && (isToExclude=="true") ) continue;
		
		switch ( el.type.toLowerCase() ) 
    { 
      case "hidden": 
                          // Gestione editor HTML 
			                    if ( el.XEditor ) el.value = el.XEditor.getValue();
			case "text": 
			case "password": 
			case "textarea": 
			case "select": 
			case "select-one":	
                          // Faccio scattare la funzione di controllo se è impostata
                          if ( el.chkFn )
                          {
                            result = this.errFn.check( el.chkFn() );
                          
                            if ( !result )
                            {
                              if (this.sequentially)
                              {
                                return false;
                              }
                              else
                              {
                                test = false;
                              }
                            }

                          }
                          
                          // Se ajax è impostato devo settare la query string  el.name + "=" + el.value + "&";
                          if (this.ajax) AjCall.addQueryString(el.name,el.value);
                  				break;
                  				
			case "radio":       break; 
			
			case "checkbox": 
			                    if ( el.chkFn )
                          {
                            result = this.errFn.check(el.chkFn());
                            
                            if ( !result )
                            {
                              if (this.sequentially)
                              {
                                return false;
                              }
                              else
                              {
                                test = false;
                              }
                            }
                          }
                          
              					  if ( el.checked ) 
                          {
                            if (this.ajax) AjCall.addQueryString(el.name,el.value);
              				    }
                           
                				  break; 
		} 
	}
	
	// Se è impostata una ulteriore funzione di controllo la faccio scattare
  if ( ( this.controlFn ) && ( !this.controlFn() ) )
  {
    if (this.sequentially)
    {
      return false;
    }
    else
    {
      test = false;
    }
  }
  
  // Se non è sequenziale allora in caso di false devo terminare l'esecuzione ( non controllo sequentially solo x' potrebbe essere false solo se non sequenziale )
  if ( !test )
  {
    return false;
  } 
	
	// Se è impostata una funzione per il loading la faccio scattare
	if ( this.loading ) this.loading();
	
	// Se è previsto l'uso dei reset. Anche questi vanno bloccati
  var subm = getElementsByAttribute(this.obj, "input", "type", "submit"); 
  for ( var i=0; i < subm.length ; i++ ) subm[i].disabled = true;
	
	// Controllo sull'ajax per il submit normale o con XMLHttpRequest
	if ( this.ajax) 
  {
    AjCall.sendData()
  }
  else
  {
    this.obj.submit();
  }
  
}

/*************************************************************************[info]
  OBJECT:               XTable
  REQUIRED:             Framework eXtend (v2) (eXtend)
  DATA:                 06/11/2009
  COMPANY:              Onlime S.n.c.
 
  VERS:                 1.0
  LAST EDIT:            06/11/2009
  
  PURPOSE:              JavaScript per tabella
  
  TODO:                 
    - ...
    
  LIMITI:  
    - ....
    
  NOTE:
    - ... 
*******************************************************************************/
XTable = function (table)
{
  this.tab = $(table);
};

XTable.prototype.highlightRow = function( parameters )
{
  var tab = this.tab;
  
  if ( !parameters ) parameters = {};    
  var startBg = parameters["fromColor"]   || "transparent";
  var hightBg = parameters["toColor"] || "#F6F6F6";

  lightrow = function(e)
  {
    var curr_elem = e.target || e.srcElement;
    
    var rows = tab.getElementsByTagName("tr");
    for (var i = 0; i < rows.length; i++) 
    {
      $(rows[i]).fn.css( { "background" : startBg.toString() } );
    }
          
    while ( ( curr_elem.tagName.toLowerCase() != "tr" ) && ( curr_elem.tagName.toLowerCase() != "table" ) ) curr_elem = curr_elem.parentNode;       
    if ( curr_elem.tagName.toLowerCase() == "tr" ) $(curr_elem).fn.css( { "background" : hightBg.toString() } );

  };
    
  unLight = function(e)
  {       
    var rows = tab.getElementsByTagName("tr");
    for (var i = 0; i < rows.length; i++) 
    {
      $(rows[i]).fn.css( { "background" : startBg } );
    }
  };
  
  $E.add(tab, "mouseover", lightrow, false);
  $E.add(tab, "mouseout", unLight, false);
  
};

/*************************************************************************[info]
  OBJECT:               Gallery 
  REQUIRED:             Framework eXtend ( eXtend >= 27/04/2009, Xtoolbar >= 27/04/2009 )
  DATA:                 15/03/2009
  COMPANY:              Onlime S.n.c.
 
  VERS:                 1.0
  LAST EDIT:            02/02/2010
  
  TODO:                 
    - ...           
    
  LIMITI:  
    - ...
*******************************************************************************/
(function() {
/** [Gallery OBJECT] */
Gallery = function( obj, parameters )
{
  this.divContenitore   = null;   // DOM div obj
  this.imgSlideshow     = null;   // DOM img obj
  this.imgSlideshowBack = null;   // DOM img obj
  this.divBar           = null;   // DOM div obj
  this.divComments      = null;   // DOM div obj
  this.arrJsonData      = null;
  this.currentImage     = "";
  this.positionArray    = -1;
  this.automatic        = false;  // OFF MODE
  this.automaticTime    = null;
  this.lock             = false;
  
  // JCustomEvent definition
  this.onload = new JCustomEvent( "load" );
  
  Gallery.prototype.init.apply( this, [obj,parameters] );  
};

/** init
@obj
@parameters arrJsonData
@parameters toolbarMode
@parameters automatic
@parameters automaticTime
@parameters AjaxCall
*/ 
Gallery.prototype.init = function ( obj, parameters )
{
  parameters = parameters || {};

  // Definizione elementi
  var divContenitore        = $(obj)
  var imgSlideshow          = createElement( "img" );
  var imgSlideshowBack      = createElement( "img" );
  
  // Setting proprietà
  divContenitore.style.position   = "relative";
  
  imgSlideshow.style.cssText = ("position:absolute;"
                                + "z-index:2;"
                                + "top:0;"
                                + "left:0;"
                                + "height:100%;"
                                + "width:100%;");
                                
  imgSlideshowBack.style.cssText = ("position:absolute;"
                                    + "z-index:1;"
                                    + "top:0;"
                                    + "left:0;"
                                    + "height:100%;"
                                    + "width:100%;"); 
  
  divContenitore.appendChild ( imgSlideshowBack );
  divContenitore.appendChild ( imgSlideshow );
  
  // valorizzazione variabile di classe
  this.divContenitore   = $(divContenitore);
  this.imgSlideshow     = $(imgSlideshow);
  this.imgSlideshowBack = $(imgSlideshowBack);
  
  this.imgSlideshow.fn.UI.setOpacity( 0 );
  this.imgSlideshowBack.fn.UI.setOpacity( 0 );
  
  //...
  this.arrJsonData      = parameters["arrJsonData"] || null;
  this.currentImage     = "";
  this.positionArray    = -1;
  this.automatic        = parameters["automatic"] || false;
  this.lock             = false;
  this.automaticTime    = parseInt(parameters["automaticTime"]) || 4000;
  
  if ( parameters["AjaxCall"] )
  {
    this.extractingAjaxXmlData( parameters["AjaxCall"] );
  }
  else if ( parameters["arrJsonData"] )
  {
    this.initialized();
  }
}

/** */
Gallery.prototype.initialized = function ()
{  
  if ( this.arrJsonData != null )
  {
    var preloadImage = new Array();
    
    // Preload in cache arr_image (! da verificare)
    for(i=0;i<(this.arrJsonData.length);i++)
    {
      preloadImage[i] = new Image();
      preloadImage[i].src = this.arrJsonData[i]["img"];
    }
    
    // Attivo l'avvio automatico o mi sposto subito sulla prima immagine.
    if ( this.automatic )
    {
      this.automatic = false;
      this.play();
    }
    else
    {
      this.setImage ( 0 );
    }
    
    // Fire onload Gallery Event
    this.onload.fire();
  }
};

/** */
// required response Xml
Gallery.prototype.extractingAjaxXmlData = function ( objAjax )
{ 
  if ( objAjax )
  {
    var objGallery = this;  // Closure
    
    if ( !objAjax.operation )
    {
      objAjax.responseType = "XML";
      objAjax.operation = function( responseXml )
        {
          var arrJsonData = retriveRcFromXml( "slideshow", responseXml );
          
          if ( arrJsonData )
          {
            objGallery.arrJsonData = arrJsonData;
            objGallery.initialized();
          }
        };
    }  
    // Chiamata Ajax  
    objAjax.sendData();  
  }
};

/** */
Gallery.prototype.extractingAjaxJSONData = function ( objAjax, callbackFn ){};

/** */  
Gallery.prototype.swapImage = function ( newSrcImage, callbackFn )
{
  var objGallery  = this;
  var cbFn        = callbackFn || null;
  var newImage    = newSrcImage;
    
  if ( this.imgSlideshow.src )
  { 
    var functBack = function ( eBack, idxBack )
    { 
      $E.removeIdx( idxBack );
      objGallery.imgSlideshow.fn.UI.setOpacity( 0 );
      objGallery.imgSlideshow.src = newImage;
    };
    $E.add( this.imgSlideshowBack, "load", functBack, false );
    
    var funct = function ( e, idx )
    { 
      $E.removeIdx( idx );
      this.fn.UI.fadeIn( null, cbFn ); 
    };
    $E.add( this.imgSlideshow, "load", funct, false );
   
    this.imgSlideshowBack.fn.UI.setOpacity( 100 );
    this.imgSlideshowBack.src = this.imgSlideshow.src;
  }
  else
  { 
    var funct = function ( e, idx )
    { 
      $E.removeIdx( idx );
      this.fn.UI.fadeIn( null, cbFn ); 
    };
    $E.add( this.imgSlideshow, "load", funct, false );
   
    this.imgSlideshow.fn.UI.setOpacity( 0 );
    this.imgSlideshow.src = newImage;
  }  
};
    
/** */
Gallery.prototype.setImage = function ( index )
{  
  if( (!this.lock) && (this.arrJsonData[index]) )
  {
    this.lock = true;
    
    this.positionArray = index;
    this.currentImage = this.arrJsonData[this.positionArray]["img"];
    
    // Avvio swopImage e rimozione lock
    var callbackFn = function(){ this.lock = false }.bind( this );
    this.swapImage( this.currentImage, callbackFn );
  }  
};

/** */  
Gallery.prototype.nextImage = function()
{ 
  if ( !this.lock )
  {
    this.lock = true;
    
    if( this.positionArray < this.arrJsonData.length - 1 )
    {
      this.positionArray++;
      this.currentImage = this.arrJsonData[this.positionArray]["img"];
    }
    else
    {
      this.positionArray = 0;
      this.currentImage = this.arrJsonData[this.positionArray]["img"];
    }
    
    // Avvio swopImage e rimozione lock
    var callbackFn = function(){ this.lock = false }.bind( this );
    this.swapImage( this.currentImage,callbackFn );
  }
};

/** */
Gallery.prototype.prevImage = function()
{ 
  if ( !this.lock )
  {
    this.lock = true;
    
    if( this.positionArray > 0 )
    {
      this.positionArray--;
      this.currentImage = this.arrJsonData[this.positionArray]["img"];
    }
    else
    {
      this.positionArray  = this.arrJsonData.length - 1;
      this.currentImage   = this.arrJsonData[this.positionArray]["img"];
    }
    
    // Avvio swopImage e rimozione lock
    var callbackFn = function(){ this.lock = false }.bind( this );
    this.swapImage( this.currentImage,callbackFn );
  }
};

/** */
Gallery.prototype.automaticSlide = function()
{
  if ( this.automatic )
  { 
    this.positionArray = ( this.positionArray >= this.arrJsonData.length-1 ) ? (0) : (this.positionArray+1);
    this.currentImage = this.arrJsonData[this.positionArray]["img"];
    
    objGallery = this;
    
    window.setTimeout ( function() {
      if (objGallery.automatic) {
        objGallery.swapImage ( objGallery.currentImage, objGallery.automaticSlide.bind(objGallery) );
        }
      },
      this.automaticTime
    );
  }
};

/** */  
Gallery.prototype.play = function()
{
  if ( !this.automatic )
  {
    this.automatic = true;
    this.lock = true;
    this.automaticSlide();
  }
  else
  {
    this.automatic = false;
    this.lock = false;
  }
};

/** */
Gallery.prototype.addBar = function( mode )
{
  mode = mode || 0;
  var divBar  = createElement( "div" );  // Definizione elemento contenitore html
  
  var toolbarMode = [];
  toolbarMode[0]  = ({});
  toolbarMode[1]  = ({
    "buttons"  : ["indietro","playStop","avanti"],
    "numbers"  : true 
  });
  toolbarMode[2]  = ({
    "buttons"     : ["indietro","playStop","avanti"] 
  });
  toolbarMode[3]  = ({
    "buttons"  : ["indietro","playStop","avanti","comments"],
    "numbers"  : true 
  });
    
  // Setting proprietà elemento contenitori html
  divBar.setAttribute( "id", this.divContenitore.id + "_bar" );
  
  divBar.style.cssText = ("position:absolute;"
                            + "top:100%;" 
                            + "left:0;"
                            + "z-index:3;"  
                            + "width:100%;" 
                            + "height:25px;" 
                            + "background: url('"+PATH_GALLERY+"img/divCommandBg.gif') top left repeat-x;"
                            + "margin-top:-25px;");
  
  this.divBar = this.divContenitore.appendChild ( divBar );
  
  var curMode = toolbarMode[mode];
  
  if ( curMode["buttons"] ) 
  {
    divBar.appendChild( this.addButtons( curMode["buttons"] ) );
    if ( curMode["buttons"].indexOf( "comments" )!=-1 ) this.addComments();
  }  
  if ( curMode["numbers"] ) divBar.appendChild( this.addNumbers() );
  
  this.divBar = this.divContenitore.appendChild ( divBar );
  
  // correzione posizionamento
  //divCtrl.style.marginTop             = - parseInt(divCtrl.offsetHeight);
  //divCommand.style.height             = parseInt(divCommand.offsetHeight);
  //divCommandShowHide.style.height     = parseInt(divCommandShowHide.offsetHeight);
}

/** */
Gallery.prototype.addButtons = function( buttons )
{
  var objGallery  = this; // closure
  var objTool     = null; // Oggetto XToolbar  
  
  var mappingToolbar = null;
                             
  // Definizione mappingToolbar
  mappingToolbar = ({
    //"toolbarMode" : parameters["toolbarMode"] || 0,
    //"img"         : parameters["img"] || PATH_GALLERY + "img/toolbar.png",  // Featurs
    //"stepW"       : parseInt( parameters["stepW"] ) || 16, // Featurs
    //"stepH"       : parseInt( parameters["stepH"] ) || 25, // Featurs
    "img"         : PATH_GALLERY + "img/toolbar.png",
    "stepW"       : 16,
    "stepH"       : 25,
    "buttons"     : {

        "playStop" : {
          //"offsetW"     : parseInt( parameters["offsetPlay"] ) || 7, // Featurs
          //"offsetStop" : parseInt( parameters["offsetStop"] ) || 10, // Featurs
          "offsetW"       : 7,
          "offsetStop"    : 10,
          "offsetEffects" : ({
                              "offsetOnMouseOver" : 1,
                              "offsetOnClick"     : 1
                            }),
          "action"        : [{
                              "event" : "click" , 
                              "fn"    : function () { objGallery.play(); }  
                            }] 
        },
        "avanti" : {
          //"offsetW" : parseInt( parameters["offsetAvanti"] ) || 8, // Featurs 
          "offsetW" : 8,
          "offsetEffects" : ({
                              "offsetOnMouseOver" : 1
                            }),
          "action"  : [{
            "event" : "click", 
            "fn"    : function () { objGallery.nextImage(); }  
          }]  
        },
        "indietro" : {
          //"offsetW" : parseInt( parameters["offsetIndietro"] ) || 6, // Featurs
          "offsetW" : 6,
          "offsetEffects" : ({
                              "offsetOnMouseOver" : 1
                            }),
          "action"  : [{
            "event" : "click" , 
            "fn"    : function () { objGallery.prevImage(); }  
          }]  
        },
        "comments" : {
          //"offsetW" : parseInt( parameters["offsetIndietro"] ) || 6, // Featurs
          "offsetW"       : 1,
          "offsetEffects" : ({
                              "offsetOnMouseOver" : 1,
                              "offsetOnClick"     : 1
                            }),
          "action"  : [{
            "event" : "click" , 
            "fn"    : function () {
              if ( !objGallery.divComments ) return;
              if ( objGallery.divComments.fn.css("display")=="none" )
              { 
                //objGallery.divComments.fn.UI.openAndFadeIn();
                objGallery.divComments.fn.UI.open();
              }
              else 
              { 
                //objGallery.divComments.fn.UI.fadeOutAndClose();
                objGallery.divComments.fn.UI.close();
              }   
            }  
          }]  
        }
      }
  });
  
  // Inizializzazione oggetto XToolbar
  objTool = new XToolbar ({ 
    "id"     : "", 
    "stepW"  : mappingToolbar["stepW"],
    "stepH"  : mappingToolbar["stepH"], 
    "img"    : mappingToolbar["img"]
  });
  
  for ( i=0; i<buttons.length; i++ )
  {
    cur = buttons[i];
    
    if (  mappingToolbar["buttons"][ cur ] )
    {                                       
      var el = objTool.createSpecialToolButton ({ 
        "offsetW"       : mappingToolbar["buttons"][ cur ]["offsetW"],
        "id"            : this.divContenitore.id + "_bar_" + cur, 
        "title"         : cur,
        "action"        : mappingToolbar["buttons"][ cur ]["action"],
        "offsetEffects" : mappingToolbar["buttons"][ cur ]["offsetEffects"]
      });
      
      // Setting proprietà elemento bottone objTool 
      el.style.cssText = ("float:left;");
    }  
  }
  
  var tb = objTool.create();
  tb.style.cssText = ("float:left;");
  return tb;
};

/** */
Gallery.prototype.addNumbers = function()
{
  var objGallery  = this; // closure
  
  var timer = null;
  
  var divNumbers      = createElement( "div" );
  var divMoveLeft     = createElement( "div" );
  var divMoveRight    = createElement( "div" );
  var divSpaceNumbers = createElement( "div" );
  var spanNumbers     = createElement( "span" );
  var imgPrev         = createElement( "img" );
  
  var rapporto = 30;  // percentuale dimensioni preview
  
  ht = (parseInt(this.divContenitore.offsetHeight)/100)*rapporto;
  wt = (parseInt(this.divContenitore.offsetWidth)/100)*rapporto;
  
  imgPrev.style.cssText = ("position:absolute;"
                            //+ "top: 0;"
                            //+ "left:0;"
                            + "top: 100%;"
                            + "left:100%;"
                            + "margin-left:" + (-wt-1) + "px;"  // -w preview - 1 bordo
                            + "margin-top: " + (-25-ht) + "px;" // -h bar - h preview
                            + "height:" + ht + "px;"
                            + "width:" + wt + "px;"
                            + "border-left:1px solid #686868;"
                            + "border-top:1px solid #686868;"
                            + "z-index:3;"
                            + "display:none;");
  
  this.divContenitore.appendChild ( imgPrev );
  
  var fnLoad = function (){ $(this).fn.UI.open(); };
  $E.add( imgPrev, "load", fnLoad, false );
  
  
  divNumbers.style.cssText = (  "height:25px;"
                              + "float:right;"
                              + "line-height:25px;"
                              //+ "background:#000000;" 
                              + "width:103px;"  // to fix
                              + "position:relative;"
                              + "text-align:right;"
                              + "font-family:Arial;" 
                              + "color:#F9F8F8;"
                              + "font-size:11px;");
  
  divMoveLeft.style.cssText = ( "width:10px;"
                              + "height:100%;"
                              + "text-align:center;"
                              //+ "background:yellow;"
                              + "float:left;");  
  
  divMoveRight.style.cssText = ( "width:10px;"
                               + "height:100%;"
                               + "text-align:center;"
                               //+ "background:yellow;"
                               + "float:right;" );                            
  
  divSpaceNumbers.style.cssText = ( "width:83px;"  // to fix
                                  + "height:100%;"
                                  + "white-space:nowrap;"
                                  + "overflow:hidden;"
                                  //+ "background:yellow;"
                                  + "float:left;");                                                                                  
                                    
  spanNumbers.style.cssText = ( "line-height:25px;"
                              + "display:inline-block;"
                              + "position:relative;"
                              + "left:0;"
                              + "height:100%;" );
  
  var fnClickLink = function ( e, idx, param ){ objGallery.setImage( param["idxImg"] ); };
  var fnOverLink = function ( e, idx, param ){ imgPrev.src = objGallery.arrJsonData[param["idxImg"]]["img"]; };
  var fnOutLink = function (){ $(imgPrev).fn.UI.close(); };
  
  var maxElm = this.arrJsonData.length;
  
  for ( i=0; i<maxElm; i++ )
  {
    var link = createElement( "a" );
    link.setAttribute("href", "javascript:;");
    link.style.cssText = ("color:#F9F8F8;"
                          + "text-decoration:none;"
                          + "margin:0px 3px 0px 3px;");
    
    link.innerHTML = ""+(i+1)+"";
    
    spanNumbers.appendChild ( link );
    
    $E.add( link, "click", fnClickLink, false, {"idxImg":parseInt(i)} );
    $E.add( link, "mouseover", fnOverLink, false, {"idxImg":parseInt(i)} );
    $E.add( link, "mouseout", fnOutLink, false );
  } 

  var fnMoveNumbers = function ( direction ){ 
    
    var maxScorrimento = spanNumbers.offsetWidth - divSpaceNumbers.offsetWidth;
    var x              = parseInt(spanNumbers.style.left);
    
    if ( !spanNumbers.style.left )  spanNumbers.style.left = 0;
    
    if ( direction == "left" )
    {
      if ( x > -(maxScorrimento) )  spanNumbers.style.left = ((x - 1) + "px");
    }
    else if( direction == "right" )
    {
      if ( x<0 )  spanNumbers.style.left = ((x + 1) + "px");
    }
  };
  
  var fnOver = function ( e, idx, parameters ) {
    var fn = function(){ fnMoveNumbers( parameters["toDirection"] ); };
    timer = window.setInterval( fn, 10);
  };
  
  
  var fnMouseout = function ( ) {
    if ( !timer ) return;
    clearInterval( timer );
    timer = null;  
  };
  
  if( maxElm > 7 ) // da sistemare
  {
    divMoveLeft.innerHTML   = "<a style='color:#FFF;font-weight:bold;font-size:11px;' href='javascript:;'><</a>";
    divMoveRight.innerHTML  = "<a style='color:#FFF;font-weight:bold;font-size:11px;' href='javascript:;'>></a>";
    
    $E.add( divMoveLeft, "mouseover", fnOver, false, {"toDirection":"right"} );
    $E.add( divMoveRight, "mouseover", fnOver, false, {"toDirection":"left"} );
    $E.add( divMoveLeft, "mouseout", fnMouseout, false );
    $E.add( divMoveRight, "mouseout", fnMouseout, false );  
  }
  
  // Append elementi
  divSpaceNumbers.appendChild ( spanNumbers );
  
  divNumbers.appendChild ( divMoveLeft );
  divNumbers.appendChild ( divSpaceNumbers );
  divNumbers.appendChild ( divMoveRight );
  
  return divNumbers;
};

/** */
Gallery.prototype.addComments = function()
{
  var objGallery  = this; // closure
  
  var divComments     = createElement( "div" );
  var divBgComments   = createElement( "div" );
  var pTxtComments    = createElement( "p" );
  var divTxtComments  = createElement( "div" );
  
  //ht = (parseInt(this.divContenitore.offsetHeight)-25);
  var rapporto = 25;  // percentuale dimensioni
  ht = (parseInt(this.divContenitore.offsetHeight)/100)*rapporto;
  wt = parseInt(this.divContenitore.offsetWidth);
  
  divComments.style.cssText = ( "position:absolute;"
                              //+ "top: 0;"
                              + "left:0;"
                              + "top: 100%;"
                              + "margin-top: " + (-ht-25) + "px;" // -h divComments - h bar
                              + "height: " + ht + "px;"  
                              + "width:" + wt + "px;"
                              + "border-top:1px solid #686868;"
                              + "z-index:2;" 
                              + "display:none;" );
  
  
  divBgComments.style.cssText = ( "top: 0;"
                                + "left:0;"
                                + "height:100%;"
                                + "width:100%;"
                                //+ "-khtml-opacity:.80;-moz-opacity:.80;-ms-filter:\"alpha(opacity=80)\";filter:alpha(opacity=80);opacity:.80;"
                                + "background:#3C3C3C;" );
  
  $(divBgComments).fn.UI.setOpacity( 80 );
  
  divTxtComments.style.cssText = (  "position:absolute;"
                                  + "top: 0;"
                                  + "left:0;"
                                  + "height:100%;"
                                  + "width:100%;"
                                  + "overflow:auto;" );
                             
  pTxtComments.style.cssText = (  "font-family:Arial;" 
                                + "color:#F9F8F8;"
                                + "margin:5px;"
                                + "font-size:12px;");
                                

  var fnSetTxtComments = function()
  {
    var txt = null; 
    if (objGallery.arrJsonData[objGallery.positionArray]["descrizione"]) 
    { 
      txt = (objGallery.arrJsonData[objGallery.positionArray]["descrizione"]);
    }   
      
    if ( txt!=null )
    {
      pTxtComments.innerHTML = txt;
    }
    else
    {
      pTxtComments.innerHTML = "";
    }  
  }                            
  $E.add( this.imgSlideshow, "load", fnSetTxtComments, false );                                 
  
  divTxtComments.appendChild ( pTxtComments );
  divComments.appendChild ( divBgComments );
  divComments.appendChild ( divTxtComments );
  
  this.divComments = $( this.divContenitore.appendChild ( divComments ) );
};

/* [addThumbs]
@obj : obj contenitore
@parameters classAThumbs : classe tag a thumbs
*/ 
Gallery.prototype.addThumbs = function( obj, parameters )
{
  var obj         = $(obj);
  var parameters  = parameters || {};
  var objGallery  = this; // closure
  var timer       = null;
  
  var divThumbs      = createElement( "div" );
  var divMoveLeft    = createElement( "div" );
  var divMoveRight   = createElement( "div" );
  var divSpaceThumbs = createElement( "div" );
  var spanThumbs     = createElement( "span" );
  
  var wt = parseInt(obj.offsetWidth);
  var ht = parseInt(obj.offsetHeight);
  
  if (!obj.style.textAlign) obj.style.textAlign = "center";
  
  divThumbs.style.cssText = (  "height:" + ht + "px;"
                              + "line-height:" + ht + "px;"
                              //+ "background:#000000;" 
                              + "width:" + wt + "px;"
                              + "position:relative;"
                              + "font-family:Arial;" 
                              + "color:#F9F8F8;"
                              + "font-size:11px;");
  
  divMoveLeft.style.cssText = ( "width:10px;"
                              + "height:100%;"
                              + "line-height:" + ht + "px;"
                              + "text-align:center;"
                              + "display:none;"
                              //+ "background:yellow;"
                              + "float:left;");  
  
  divMoveRight.style.cssText = ( "width:10px;"
                               + "height:100%;"
                               + "line-height:" + ht + "px;"
                               + "text-align:center;"
                               + "display:none;"
                               //+ "background:yellow;"
                               + "float:right;" );                            
  
  divSpaceThumbs.style.cssText = ( "width:" + wt + "px;"
                                  + "height:100%;"
                                  + "white-space:nowrap;"
                                  + "overflow:hidden;"
                                  //+ "background:orange;"
                                  + "float:left;");                                                                                  
                                    
  spanThumbs.style.cssText = ( "line-height:" + ht + "px;"
                              + "display:inline-block;"
                              //+ "background:green;"
                              + "position:relative;"
                              + "left:0;"
                              + "height:100%;" );
  
  var fnClickLink = function ( e, idx, param ){ objGallery.setImage( param["idxImg"] ); };
  
  var maxElm = this.arrJsonData.length;
  
  for ( i=0; i<maxElm; i++ )
  { 
    var link = createElement( "a" );
    link.setAttribute("href", "javascript:;");
    
    var img = createElement( "img" );
    img.src = this.arrJsonData[i]["thumb"];                   
    
    if ( parameters["classAThumbs"] )
    {
      link.className = parameters["classAThumbs"];
    }
    
    link.style.cssText = (  "font-size:0px;"
                          + "display:inline-block;"
                          + "height:" + ht + "px;" );
    
    img.style.cssText = ( "border:0;"
                        + "height:100%;"
                        + "width:auto;"
                        + "font-size:0px;");
                        
    link.appendChild ( img );
    spanThumbs.appendChild ( link );   
    
    $E.add( link, "click", fnClickLink, false, {"idxImg":parseInt(i)} );
  } 

  var fnMoveThumbs = function ( direction ){ 
    
    var maxScorrimento = spanThumbs.offsetWidth - divSpaceThumbs.offsetWidth;
    var x              = parseInt(spanThumbs.style.left);
    
    if ( !spanThumbs.style.left )  spanThumbs.style.left = 0;
    
    if ( direction == "left" )
    {
      if ( x > -(maxScorrimento) )  spanThumbs.style.left = ((x - 1) + "px");
    }
    else if( direction == "right" )
    {
      if ( x<0 )  spanThumbs.style.left = ((x + 1) + "px");
    }
  };
  
  // Append elementi
  divSpaceThumbs.appendChild( spanThumbs );
  divThumbs.appendChild( divMoveLeft );
  divThumbs.appendChild( divSpaceThumbs );
  divThumbs.appendChild( divMoveRight );
  obj.appendChild( divThumbs );
  
  if( parseInt(spanThumbs.offsetWidth) > parseInt(divSpaceThumbs.offsetWidth) )
  {
    divMoveLeft.style.display   = "block";
    divMoveRight.style.display  = "block";
    divSpaceThumbs.style.width  = (wt-20) + "px";
    
    var fnOver = function ( e, idx, parameters ) {
      var fn = function(){ fnMoveThumbs( parameters["toDirection"] ); };
      timer = window.setInterval( fn, 10);
    }; 
    
    var fnMouseout = function ( ) {
      if ( !timer ) return;
      clearInterval( timer );
      timer = null;  
    };
  
    divMoveLeft.innerHTML   = "<a style='color:#505050;text-decoration:none;display:block;font-weight:bold;font-size:11px;' href='javascript:;'><</a>";
    divMoveRight.innerHTML  = "<a style='color:#505050;text-decoration:none;display:block;font-weight:bold;font-size:11px;' href='javascript:;'>></a>";
    
    $E.add( divMoveLeft, "mouseover", fnOver, false, {"toDirection":"right"} );
    $E.add( divMoveRight, "mouseover", fnOver, false, {"toDirection":"left"} );
    $E.add( divMoveLeft, "mouseout", fnMouseout, false );
    $E.add( divMoveRight, "mouseout", fnMouseout, false );  
  }
  
  return true;
};
/** [END Gallery OBJECT] */
})();
/*************************************************************************[info]
  OBJECT:               XPassword
  REQUIRED:             Framework eXtend (v2) (eXtend)
  DATA:                 06/11/2009
  COMPANY:              Onlime S.n.c.
 
  VERS:                 1.0
  LAST EDIT:            06/11/2009
  
  PURPOSE:              JavaScript per modulo xPassword
  
  TODO:                 
    - ...
    
  LIMITI:  
    - ....
    
  NOTE:
    -... 
*******************************************************************************/
(function() {
XPassword = function ( pwd, rpwd, error, cerror )
{
  this.pwd  = $(pwd);
  this.rpwd = $(rpwd);
  
  this.init.apply( this, [error, cerror] );
};

XPassword.prototype.init = function( error, cerror )
{
  var re = new RegExp("^[A-Za-z0-9]{6,20}$");
  this.pwd.setAttribute("maxlength", "20");
  $C( this.pwd ,"stringFilter", { "minLen" : 6 ,"regex" : re }, error);    // passo la prima parte dei parametri
  
  if ( this.rpwd )
  {
    var pwd_field   = this.pwd;
    var rpwd_field  = this.rpwd;
    
    if (!cerror) cerror = {};
    rpwd_field.response = {
                              "fieldname" :  ( cerror["fieldname"] || rpwd_field.id ) , 
                              "obj"       :  ( cerror["obj"] || rpwd_field ),
                              "container" :  ( cerror["container"] || rpwd_field ),
                              "response"  :  ( cerror["response"] || rpwd_field )
                           };
    
    controlpwd = function()
    {
    
      if (pwd_field.value != rpwd_field.value )
      {
        rpwd_field.response["errno"] = "8";
        return rpwd_field.response;
      }
      
      delete rpwd_field.response["errno"]; 
      return rpwd_field.response;                // response corretta
    }

    rpwd_field.chkFn = controlpwd; 
  }
}
})();
/*************************************************************************[info]
  OBJECT:               XMultiple
  REQUIRED:             Framework eXtend (v2) (eXtend)
  DATA:                 06/11/2009
  COMPANY:              Onlime S.n.c.
 
  VERS:                 1.0
  LAST EDIT:            06/11/2009
  
  PURPOSE:              ...
  
  TODO:                 
    - ...
    
  LIMITI:  
    - ....
    
  NOTE:
  
    Probabilmente è necessaria una modifica alla xform perchè dobbiamo controllare se il campo era obbligatorio o no. E non possiamo controllare
    i singoli hidden. Probabilmente dovremo agire sull'oggetto di partenza settando un attributo che dica quanti elementi sono presenti. Oppure meglio
    ancora creando appositamente un hidden che deve essere mantenuto. In questo modo la tecnica può essere usata per altri comportamenti.
    MANCA!!! la gestione ( tramite hidden che memorizza il numero di elementi dell'obbligatorietà - vedere xfile.js con checkvalue)  
*******************************************************************************/
(function() {
// Definizione di comportamento multiplo
XMultiple = function( parameters )
{
  this.buildFn  =   null;
  this.inputFn  =   null;
  this.event    =   null;
  this.addFn    =   null;
  
  XMultiple.prototype.init.apply( this, [parameters] );
};


XMultiple.prototype.init = function( parameters )
{ 
  this.buildFn      = parameters["buildFn"] ||  null;
  this.inputFn      = parameters["inputFn"] ||  null;
  this.event        = parameters["event"]   ||  null;
  this.addFn        = parameters["addFn"]   ||  null;
  
  // Closure per identificare l'istanza
  var instance    = this;
  
  // Funzione per l'inizializzazione della struttura ( elementi già selezionati)
  instance.buildFn();
  
  // Comportamento per l'aggiunta di un elemento alla lista
  var addFunction = function ( e, idx, param )
                    {
                       var val = instance.inputFn();
                       instance.addFn( val );
                    };
        
  $E.add ( $(this.event["obj"]), this.event["evt"], addFunction, false, null );
  
}


// Oggetto SELECT MULTIPLA

XSelect = function( parameters, errMessage )
{
  this.init( parameters, errMessage );
};

XSelect.prototype.init = function( parameters, errMessage )
{
  var objSel    = $(parameters["obj"])        ||  null;
  var event     = parameters["event"]         ||  null;  
  var container = $(parameters["container"])  ||  null;
  var limit     = parameters["limit"]         ||  null;
  var optional  = parameters["optional"];  
  var duplicate = parameters["duplicate"];

  container.className = "XS_container";
  
  objList = createElement( "ul", objSel.id + "_list" );
  objList.setAttribute("id", objSel.id + "_list" );
  objList.className = "XS_list";
  
  container.appendChild(objList);
  
  // Funzione di selezione dell'input
  var selInput =  function()
                  {
                    var ret = { 
                                "val" : objSel.value ,
                                "str" : objSel.options[objSel.selectedIndex].text
                              }; 
                    return ret; 
                  };
  
  // Funzione di aggiunta di un elemento
  var addElem =   function( arg )
                  { 
                    // dobbiamo controllare che il valore non sia vuoto e che non sia duplicato.
                    if ( trim(arg["val"]) == "" )  return false;
                    
                    // Dovremmo anche capire se i duplicati sono ammessi oppure no. Possiamo farlo tramite una variabile
                    // Dell'oggetto che viene impostata e passata o come argomento o come closure.
                    if (duplicate == false)
                    {
                      var els = getElementsByNameCross( objSel.id + "_value[]", "input");

                      for ( var i=0; i<els.length; i++)
                      {
                        if ( els[i].value == arg["val"] ) return false;
                      }
                    }
 
                    // Forse dobbiamo anche limitare i caratteri mostrati per ciascun elemento
                    objElem = createElement( "li", "" );
                                        
                    objSpan = createElement( "span", "" );
                    
                    if ( ( limit != null) && ( limit < arg["str"].length ) )
                    {
                      arg["str"]  = arg["str"].substring(0, ( limit - 1 ) ) + "...";        
                    }
                    
                    objSpan.innerHTML = arg["str"]; 
                    
                    objHidden  = createElement( "input", objSel.id + "_value[]" );
                    objHidden.setAttribute('id', objSel.id + "_value[]" );          
                    objHidden.setAttribute('type', 'hidden');
                    objHidden.setAttribute('value', arg["val"]);
                    
                    objDel  = createElement("img", "");
                    objDel.src = PATH_XSELECT + "img/transparent.gif";
                    objDel.style.cursor = "pointer";
                    
                    var delFn = function (e, idx)
                                {
                                  // Devo rimuovere l'evento della X
                                  $E.removeIdx(idx);
                                  
                                  // Rimuovo l'elemento li corrispondente
                                  this.parentNode.parentNode.removeChild(this.parentNode);
                                }
                    
                    $E.add ( objDel, "click", delFn, false, null );
                    
                    objElem.appendChild(objSpan);
                    objElem.appendChild(objDel);
                    objElem.appendChild(objHidden);
                    
                    objList.appendChild(objElem);
                    
                    for ( var i=0; i<objSel.options.length; i++)
                    {  
                      if ( objSel.options[i].value == arg["val"] ) objSel.options[i].selected = false;
                    }
                     
                  };
  
  // Funzione di inizializzazione
  var initElem =  function( )
                  { 
                    // Controllo la presenza di valori selezionati
                    for ( var i=0; i<objSel.options.length; i++)
                    {
                      if (objSel.options[i].selected == true)
                      {
                        addElem ( { "val" : objSel.options[i].value, "str" : objSel.options[i].text } );
                        objSel.options[i].selected = false;
                      }                     
                    }
                    // Trasformo la select multipla in singola
                    objSel.multiple = false;
                  };    
  
  // Creo il comportamento
  behavior = new XMultiple( {
                                "buildFn" : initElem,
                                "inputFn" : selInput,
                                "event"   : event,
                                "addFn"   : addElem 
                            } );
  
  // Gestione errori ( campo obbligatorio )
  if (!errMessage) errMessage = {};
  objSel.response =  {
                        "fieldname" :  ( errMessage["fieldname"] || objSel.id ) , 
                        "obj"       :  ( errMessage["obj"] || objSel ),
                        "container" :  ( errMessage["container"] || objSel ),
                        "response"  :  ( errMessage["response"] || objSel )
                     };
  
  var checkValue =  function()
                    {
                      if (!optional)
                      {
                        var els = getElementsByNameCross( objSel.id + "_value[]", "input");
                        if( els.length == 0 )
                        {
                          objSel.response["errno"] = "1";
                          return objSel.response;
                        }
                      }
                      
                      delete objSel.response["errno"];
                      return objSel.response;
                    };
  
  objSel.chkFn = checkValue;
}
})();
/*************************************************************************[info]
  OBJECT:               Notify
  REQUIRED:             Framework eXtend (v2) (eXtend)
  DATA:                 24/09/2009
  COMPANY:              Onlime S.n.c.
 
  VERS:                 1.0
  LAST EDIT:            03/11/2009
  
  PURPOSE:              Notifiche
  
  TODO:                 
    - ...
    
  LIMITI:  
    - ....
*******************************************************************************/
(function() {
/*******************************************************************************
  [Notify OBJECT]  
*******************************************************************************/
Notify = {};
/*******************************************************************************
  [Notify.message OBJECT]  
*******************************************************************************/ 
Notify.message = function( txt, param )
{ 
  Notify.message.setParam( param );
     
  if( Notify.message.objContainer==null )
  {
    var divConteiner    = createElement( "div" );
    Notify.message.objContainer = document.body.appendChild( divConteiner );
    Notify.message.objContainer.style.cssText = ( "display:none;"
                                                + "padding:0;"
                                                + "margin:0;"
                                                + "top:0px;"
                                                + "width:100%;"
                                                + "text-align:center;"
                                                + "left:0px;"
                                                + "z-index:100;"
                                                + "position:fixed;" );
    
    if( Notify.message.objInner==null )
    {
      Notify.message.objInner = Notify.message.objContainer;
    }                                                           
  }
  
  Notify.message.objInner.innerHTML = "";
  if( typeOf(txt) == 'string' ) Notify.message.objInner.innerHTML = txt;
  else Notify.message.objInner.appendChild( txt );
  
  var aButton = createElement( "a" );
  aButton.style.cssText = ( "margin:0 0 0 5px;" );
  aButton.className = "onlime-button";
  aButton.innerHTML = "<span class=\"onlime-tick\">Chiudi</span>";
  Notify.message.objInner.appendChild( aButton );
  
  $E.add( aButton,"click", Notify.message.hide, false );
  
     
  // closure closureTime
  var closureTime = Notify.message.closureTime;
     
  var fnAfterShow = function(){
    if( closureTime!=null ) window.setTimeout( Notify.message.hide, closureTime );
  };
  
  if( Notify.message.useFade ) $( Notify.message.objContainer ).fn.UI.openAndFadeIn(null,null,fnAfterShow);
  else $( Notify.message.objContainer ).fn.UI.open(null,fnAfterShow);
};

//                  
Notify.message.hide = function()
{ 
  if( Notify.message.useFade ) $( Notify.message.objContainer ).fn.UI.fadeOutAndClose();
  else $( Notify.message.objContainer ).fn.UI.close();
};

//                  
Notify.message.setParam = function( param )
{ 
  param = param || {};
  if( !isNaN(param["closureTime"]) && (param["closureTime"]>=0) )
  {
    if( param["closureTime"]===0 )  Notify.message.closureTime = null;
    else{ Notify.message.closureTime = param["closureTime"]; }
  }
  
  (param["objContainer"]) ? (Notify.message.objContainer = Notify.message.objInner = $(param["objContainer"])) : (null);
  (param["objInner"])     ? (Notify.message.objInner = $(param["objInner"])) : (null);
  ((param["useFade"]) && ( (param["useFade"]===true) || (param["useFade"]===false) )) ? (Notify.message.useFade = param["useFade"]) : (null);
};

//            
Notify.message.objContainer = null;
Notify.message.objInner     = null;
Notify.message.closureTime  = null;
Notify.message.useFade      = false;
// JCustomEvent                             
Notify.message.onafterhide = new JCustomEvent( "afterhide" );
Notify.message.onaftershow = new JCustomEvent( "aftershow" );
/*******************************************************************************
  [END Notify.message OBJECT]  
*******************************************************************************/
/*******************************************************************************
  [Notify.alert OBJECT]  
*******************************************************************************/           
Notify.alert = function( txt, param, fnOnConfirm )
{
  param = param || {};
  Notify.alert.setParam( param );
  var textConfirmButton = param["textConfirmButton"] || "Ok";
  var fnOnConfirm       = fnOnConfirm || function(){};
  
  if( Notify.alert.objContainer==null )
  {
    var divConteiner = createElement( "div" );
    Notify.alert.objContainer = document.body.appendChild( divConteiner );
    Notify.alert.objContainer.style.cssText = ( "padding:10px;"
                                              + "margin:0;"
                                              + "width:200px;"
                                              + "text-align:center;" );
    
    if( Notify.alert.objInner==null )
    {
      Notify.alert.objInner = Notify.alert.objContainer;
    }                                                           
  }
  
  Notify.alert.objInner.innerHTML = "";
  if( typeOf(txt) == 'string' ) Notify.alert.objInner.innerHTML = txt;
  else Notify.alert.objInner.appendChild( txt );
  
  var divButton   = createElement( "div" );
  divButton.style.cssText = ( "border-top:3px double #909090;text-align:center;margin:5px 0 0 0;padding:5px 0 0 0;" );
  var aButton = createElement( "a" );
  aButton.className = "onlime-button";
  aButton.innerHTML = "<span class=\"onlime-tick\">" + textConfirmButton + "</span>";
  divButton.appendChild( aButton );
  Notify.alert.objInner.appendChild( divButton );
  
  var fnClickAButton = function(){
                            fnOnConfirm();
                            Notify.alert.hide();
                          };
  $E.add( aButton, "click", fnClickAButton, false );
  
  if( LightWindowT.obj )
  {
    LightWindowT.swapObject( Notify.alert.objContainer );
  }
  else
  {
    LightWindowT.init( Notify.alert.objContainer );
  }
  
  if( Notify.alert.useFade ) LightWindowT.showWithFade();
  else LightWindowT.show();
};

//
Notify.alert.hide = function()
{
  if( Notify.alert.useFade ) LightWindowT.hideWithFade();
  else LightWindowT.hide();
};

//                  
Notify.alert.setParam = function( param )
{ 
  param = param || {};
  (param["objContainer"]) ? (Notify.alert.objContainer = Notify.alert.objInner = $(param["objContainer"])) : (null);
  (param["objInner"])     ? (Notify.alert.objInner = $(param["objInner"])) : (null);
  ((param["useFade"]) && ( (param["useFade"]===true) || (param["useFade"]===false) )) ? (Notify.alert.useFade = param["useFade"]) : (null);
};

Notify.alert.objContainer = null;
Notify.alert.objInner     = null;
Notify.alert.useFade      = false;
/*******************************************************************************
  [END Notify.alert OBJECT]  
*******************************************************************************/
/*******************************************************************************
  [Notify.confirm OBJECT]  
*******************************************************************************/ 
Notify.confirm = function ( txt, param, fnOnConfirm, fnOnAbort )
{
  param = param || {};
  Notify.confirm.setParam( param );
  var textConfirmButton = param["textConfirmButton"] || "Applica";
  var textAbortButton   = param["textAbortButton"] || "Annulla";
  var fnOnConfirm       = fnOnConfirm || function(){};
  var fnOnAbort         = fnOnAbort || function(){};
  
  if( Notify.confirm.objContainer==null )
  {
    var divConteiner = createElement( "div" );
    Notify.confirm.objContainer = document.body.appendChild( divConteiner );
    Notify.confirm.objContainer.style.cssText = ( "padding:10px;"
                                                + "margin:0;"
                                                + "width:200px;"
                                                + "text-align:center;" );
    
    if( Notify.confirm.objInner==null )
    {
      Notify.confirm.objInner = Notify.confirm.objContainer;
    }                                                           
  }
  
  Notify.confirm.objInner.innerHTML = "";
  if( typeOf(txt) == 'string' ) Notify.confirm.objInner.innerHTML = txt;
  else Notify.confirm.objInner.appendChild( txt );
  
  var divButton   = createElement( "div" );
  divButton.style.cssText = ( "border-top:3px double #909090;text-align:center;margin:5px 0 0 0;padding:5px 0 0 0;" );
  
  var aConfirmButton = createElement( "a" );
  aConfirmButton.className = "onlime-button";
  aConfirmButton.style.cssText = ( "margin-right:5px;" );
  aConfirmButton.innerHTML = "<span class=\"onlime-tick\">" + textConfirmButton + "</span>";
  divButton.appendChild( aConfirmButton );
  
  var aAbortButton = createElement( "a" );
  aAbortButton.className = "onlime-button";
  aAbortButton.innerHTML = "<span class=\"onlime-cross\">" + textAbortButton + "</span>";
  divButton.appendChild( aAbortButton );
  
  Notify.confirm.objInner.appendChild( divButton );
  
  var fnClickAConfirmButton = function(){
                                fnOnConfirm();
                                Notify.confirm.hide();
                              };
  $E.add( aConfirmButton, "click", fnClickAConfirmButton, false );
                          
  var fnClickAAbortButton = function(){
                              fnOnAbort();
                              Notify.confirm.hide();
                            };
                                                  
  $E.add( aAbortButton, "click", fnClickAAbortButton, false );
  
  if( LightWindowT.obj )
  {
    LightWindowT.swapObject( Notify.confirm.objContainer );
  }
  else
  {
    LightWindowT.init( Notify.confirm.objContainer );
  }
  
  if( Notify.confirm.useFade ) LightWindowT.showWithFade();
  else LightWindowT.show();
};

//
Notify.confirm.hide = function()
{
  if( Notify.confirm.useFade ) LightWindowT.hideWithFade();
  else LightWindowT.hide();
};

//                  
Notify.confirm.setParam = function( param )
{ 
  param = param || {};
  (param["objContainer"]) ? (Notify.confirm.objContainer = Notify.confirm.objInner = $(param["objContainer"])) : (null);
  (param["objInner"])     ? (Notify.confirm.objInner = $(param["objInner"])) : (null);
  ((param["useFade"]) && ( (param["useFade"]===true) || (param["useFade"]===false) )) ? (Notify.confirm.useFade = param["useFade"]) : (null);
};

Notify.confirm.objContainer = null;
Notify.confirm.objInner     = null;
Notify.confirm.useFade      = false;
/*******************************************************************************
  [END Notify.confirm OBJECT]  
*******************************************************************************/
/*******************************************************************************
  [END Notify OBJECT]  
*******************************************************************************/
})();
/*************************************************************************[info]
  OBJECT:               Rank
  REQUIRED:             Framework eXtend (v2) (eXtend)
  DATA:                 09/07/2009
  COMPANY:              Onlime S.n.c.
 
  VERS:                 1.0
  LAST EDIT:            30/09/2009
  
  PURPOSE:              Rank
  
  TODO:                 
    - ..
*******************************************************************************/
(function() {
/*******************************************************************************
  [Rank OBJECT]  
*******************************************************************************/

/**
*	@class Rank 
*	@param {Object} obj
*	@param {Object} parameters
*/
Rank = function ( obj, parameters )
{
  this.obj            = null;
  this.aDegrees       = null;
  this.degrees        = null;
  this.curRank        = null;
  this.state          = null;
  this.img            = {"src":null,"h":null,"w":null};
  this.idxEvMouseOut  = null;
  this.idxEvMouseOver = null;
  this.idxEvClick     = null;
  
  // JCustomEvent definition
  this.onload  = new JCustomEvent( "load" );
  this.onclick = new JCustomEvent( "click" );

  var objRank = this; //closure
  var imm     = new Image();
  var fnInit  = Rank.prototype.init.bind( objRank, obj, parameters );
  $E.add(imm,"load",function(){ 
                        objRank.img["src"]  = this.src;
                        objRank.img["h"]    = parseFloat(this.height); 
                        objRank.img["w"]    = parseFloat(this.width)/2;
                        // init
                        fnInit();
                      },false);
  
  parameters = parameters || {};                    
  imm.src = (parameters["img"]) ? (parameters["img"]) : (PATH_RANK+"/img/stars.gif");
};

/**
*	init Rank
*	@param {Object} obj
*	@param {Object} parameters
*/
Rank.prototype.init = function ( obj, parameters )
{ 
  parameters = parameters || {};
  
  this.obj        = $(obj);
  this.curRank    = (parseInt(parameters["curRank"]) || 0);
  this.degrees    = (parseInt(parameters["degrees"]) || 5);
  
  var objRank     = this; //closure
  
  this.aDegrees = [];
  for( var i=0;i<this.degrees;i++ )
  {
    var aDegree = createElement( "a" );
    
    aDegree.setAttribute("title",i+1);
    
    aDegree.style.cssText = ( "height:"+this.img["h"]+"px;"
                            + "width:"+this.img["w"]+"px;"
                            + "overflow:hidden;"
                            + "display:block;"
                            + "border:0;"
                            + "cursor:pointer;"
                            + "float:left;"
                            + "background: url('"+this.img["src"]+"') 0 0 no-repeat;" );
    
    aDegree.value = i+1;
    
    this.aDegrees.push( this.obj.appendChild( aDegree ) );
  }
  
  /*
  var divClear = createElement( "div" );
  divClear.style.cssText = ( "height:0px;"
                            + "line-height:0;"
                            + "overflow:hidden;"
                            + "clear:both;" );
                            
  this.obj.appendChild( divClear );
  */
  
  var fnEvMouseOver = function( e,idx,opt ){
    var relTarg = $E.getTarget( e );
    if( !isChildOf( relTarg, this ) || (!relTarg.value) ) return;
    for(var i=0;i<objRank.aDegrees.length;i++) objRank.aDegrees[i].style.backgroundPosition = "0 0";
    for(var i=0;i<relTarg.value;i++) objRank.aDegrees[i].style.backgroundPosition = "-"+objRank.img["w"]+"px 0";
  };
  this.idxEvMouseOver = $E.add( this.obj, "mouseover", fnEvMouseOver, false );
  
  var fnEvMouseOut = function( e,idx,opt ){
    //var relTarg = $E.getTarget( e );
    //if( isChildOf( relTarg, this ) return;
    for(var i=0;i<objRank.aDegrees.length;i++) 
    { 
      if( (i+1)>objRank.curRank ) objRank.aDegrees[i].style.backgroundPosition = "0 0";
      else objRank.aDegrees[i].style.backgroundPosition = "-"+objRank.img["w"]+"px 0";
    }
  };
  this.idxEvMouseOut = $E.add( this.obj, "mouseout", fnEvMouseOut, false );
  
  var fnEvClick = function( e,idx,opt ){
    var relTarg = $E.getTarget( e );
    if( !isChildOf( relTarg, this ) || (!relTarg.value) ) return;
    objRank.onclick.fire( {"value": relTarg.value} );
  };
  this.idxEvClick = $E.add( this.obj, "click", fnEvClick, false );
  
  // setCurRank
  this.setCurRank( this.curRank );
  
  this.onload.fire();
                           
  return true;
};

/**
*	lock Rank
*/
Rank.prototype.lock = function ()
{
  if( !this.state )
  {
    $E.deactiveIdx( this.idxEvMouseOut );
    $E.deactiveIdx( this.idxEvMouseOver );
    $E.deactiveIdx( this.idxEvClick );
    this.state = true;
    return true;
  }
  return false;  
};

/**
*	unlock Rank
*/
Rank.prototype.unlock = function ()
{
  if( this.state )
  {
    $E.activeIdx( this.idxEvMouseOut );
    $E.activeIdx( this.idxEvMouseOver );
    $E.activeIdx( this.idxEvClick );
    this.state = false;
    return true;
  }
  return false;  
};

/**
*	setCurRank Rank
*/
Rank.prototype.setCurRank = function ( number )
{
  this.curRank = parseInt(number);
  for(var i=0;i<this.aDegrees.length;i++) 
  { 
    if( (i+1)>this.curRank ) this.aDegrees[i].style.backgroundPosition = "0 0";
    else this.aDegrees[i].style.backgroundPosition = "-"+this.img["w"]+"px 0";
  }
  return true;
};
/*******************************************************************************
  [END Rank OBJECT]  
*******************************************************************************/
})();

