// =============================================================================
//  Invia una richiesta JSON e passa la risposta alla funzione fnResult()
// =============================================================================

function cfRequestJSON( reqPath, fnResult ) {  

  var jreq = new Request.JSON({ url: reqPath,
      onComplete: function( j ) {   
          if ( $chk(j) ) {     
            fnResult( ($chk( j.answer ) ? j : {"answer": {"errnum":-2,"errdesc":"Risposta del server non leggibile" }} ) );
          }
          else {
            fnResult( {"answer": {"errnum":-1,"errdesc":"Errore connessione al server" }} );
          }      
      }         
  }).send();
}

// =============================================================================
//  Invia una richiesta Submit di un form e 
//  passa la risposta alla funzione fnResult()
// =============================================================================

function cfRequestSubmit( formId, fnResult ) {  

  $( formId ).set('send', {
      method: 'post',
      encoding: 'Windows-1251',  
      onComplete: function( o ) {          
          if ( $chk(o) ) {
            var j = JSON.decode( o );               
            fnResult( ($chk( j.answer ) ? j : {"answer": {"errnum":-2,"errdesc":"Risposta del server non leggibile" }} ) );
          }
          else {
            fnResult( {"answer": {"errnum":-1,"errdesc":"Errore connessione al server" }} );
          }      
      }
  });
  $( formId ).send();
}  

// =============================================================================
//  Visualizza un messaggio temporaneo
// =============================================================================

function cfShowMessageEl( el, txt ) {
  el.setStyles( {'opacity': 0} );         
  el.innerHTML = txt;
  el.morph( {'opacity': 1} );
  (function() { el.morph( {'opacity': 0} ) }).delay( 3000, this );  
}

// =============================================================================
//  Image
// =============================================================================
	
var cfImage = new Class({
	
  Implements: [Events, Options],

  options: { 
    left:0, 
    top:0, 
    width:600, 
    height:100,  
    imgPath: './images',      
    imgFile: null,
    imgRef: null,
    duration: 'normal',                  // durata transizione  
    phpThumbFile: 'cflibs/cf-image.php',  
    dClass:'cf-Im',  
    // Events
    onImgChange: $empty   	              
	},

	initialize: function( container, options ) {    	
		this.setOptions(options);
    var to = this.options;	

    // img che contiene l'immagine attualmente in uso		
		this.actImg = null;
		this.tmpImg = null;
		this.infoActive = false;
		
    // Elemento Master
    this.imEl = new Element('div', {        
      'class': to.dClass,     
      'styles': {'top': to.top, 'left': to.left, 'width': to.width, 'height': to.height}
    }).inject( container );   
    
    if (to.imgFile != null) { this.ShowImage( to.imgPath, to.imgFile, to.imgRef ); }
  },
  
  ShowImage: function( basePath, imgName, imgRef ) {    
    var to = this.options;
    this.imgPath = basePath;
    this.imgFile = imgName;
    this.imgInfo = imgRef;
    var  imgLink = to.phpThumbFile +'?width='+to.width+ '&' +
                                     'height='+to.height+ '&' +
                                     'src=' + basePath + '/' + imgName; 
    this._showRef( false );                      
    this._showLoader( true );
    this.tmpImg = new Asset.image( imgLink, { 
        onload: function() {   
          this.tmpImg.setStyles({'opacity':0}); 
          this.tmpImg.inject( this.imEl );               
          var sz = this.tmpImg.getSize();
          var my = (to.height - sz.y) / 2;
          var mx = (to.width - sz.x) / 2;                 
          this.tmpImg.setStyles( {'position':'absolute', 'left':mx,'top':my} );         
          
          this._showLoader( false );
          if (this.actImg != null) this.actImg.tween( 'opacity', 0 );
          var e = new Fx.Morph(this.tmpImg, { duration: to.duration } );
          e.start( {'opacity': [0, 1]} ).chain(      
            function() {              
              this._showRef( true );
              this._sobstituteImg();    
             }.bind( this )                      
          );              
        }.bind( this )              
    });
  },

  _showRef: function( sts ) {
    if (this.imgInfo == null) {
      if (this.infoEl != null) this.infoEl.destroy();
      return;
    } 
     
    if ( sts ) {
      // Info Box    
      this.infoEl = new Element('div', {
        'class':'info', 'styles':{'opacity':0},'morph':{duration: 'short'}
      }).inject( this.imEl );      
      
      this.fireEvent( "imgChange", { "el": this.infoEl, "ref": this.imgInfo } );
      this.infoEl.morph( {'opacity': 1} );
      return;
    }  
    
    if (this.infoEl == null) return;          

    var e = new Fx.Morph(this.infoEl, { duration: 'short' } );
    e.start( {'opacity': 0} ).chain(        
      function() { this.infoEl.destroy(); }.bind( this )            
    );    
  },

  _sobstituteImg: function() {
    if (this.actImg != null) this.actImg.destroy();         
    this.actImg = this.tmpImg;
    this.tmpImg = null;       
  },
  
  _showLoader: function( sts ) {    
    if ( this.loaderEl != null ) this.loaderEl.destroy();
    if ( sts == false ) return;
          
    this.loaderEl = new Element('div', {  
      'class': 'loader',    
      'styles': { 
        'top': (this.options.height - 48) / 2, 
        'left':(this.options.width  - 48) / 2
      }
    }).inject( this.imEl );    
  } 
});  

// =============================================================================
//  ImageList
// =============================================================================
	
var cfImageList = new Class({
	
  Implements: [Events, Options],

  options: { 
    left:0, 
    top:0, 
    width:600, 
    height:100, 
    nrPics:5,    
    imgsPath: './images',
    imgsList: null,
    duration: 300,                  // durata transizione
    phpThumbFile: 'cflibs/cf-image.php',
    dClass:'cf-ImLi',   	
    // Events
    onClick: $empty	              
	},

	initialize: function( container, options ) {    	
		this.setOptions(options);
    var tmpO = this.options;
 	
    // Cacoliamo quante pics visibili e lo spazio tra le pics
    
    this.npics   = tmpO.nrPics;
    this.thWidth = Math.floor( (tmpO.width - 40) / this.npics );    
	  this.spics = Math.floor( (tmpO.width - 40 - (this.npics * this.thWidth)) / (this.npics - 1) );
		
    // Elemento Master
    this.imEl = new Element('div', {        
      'class': tmpO.dClass,     
      'styles': {'top': tmpO.top, 'left': tmpO.left, 'width': tmpO.width, 'height': tmpO.height}
    }).inject( container );
    
    // Left buttons
    this.btlEl = new Element('div', {
      'class': 'cf-ImLi-btns',      
      'styles': {'left':0, 'top':0, 'width':20, 'height':tmpO.height }
    }).inject( this.imEl ); 
    this.btnL = new Element('div', {
      'class': 'btnL',      
      'events': { 'click': function(e) { e.stop; this.ScrollImgs( -1 ); }.bind(this) }
    }).inject( this.btlEl );     
    this.btnLL = new Element('div', {
      'class': 'btnLL',      
      'events': { 'click': function(e) { e.stop; this.ScrollImgs( -(this.npics - 1) ); }.bind(this) }
    }).inject( this.btlEl );     
    
    // Thumb Area (maschera)
    this.thEl = new Element('div', {
      'class': 'thbase',      
      'styles': {'width': tmpO.width - 40, 'height':tmpO.height, 'left':20, 'top':0 }
    }).inject( this.imEl );    

    // Right buttons
    this.btrEl = new Element('div', {      
      'class': 'cf-ImLi-btns',      
      'styles': {'left':tmpO.width - 20, 'top':0, 'width':20, 'height':tmpO.height }
    }).inject( this.imEl );          
    this.btnR = new Element('div', {
      'class': 'btnR',      
      'events': { 'click': function(e) { e.stop; this.ScrollImgs( 1 ); }.bind(this) }
    }).inject( this.btrEl );     
    this.btnRR = new Element('div', {
      'class': 'btnRR',      
      'events': { 'click': function(e) { e.stop; this.ScrollImgs( (this.npics - 1) ); }.bind(this) }
    }).inject( this.btrEl );     
        
    // Thumb Area (Slide con tutte le pics)
    this.slideEl = new Element('div', {   
      'class': 'thslide',      
      'styles': { 'left':0, 'height': tmpO.height, 'width': 200 + (tmpO.imgsList.length * (this.thWidth+this.spics)) }      
    }).inject( this.thEl );    
    
    if (tmpO.imgsList != null) this.SetImgsList( tmpO.imgsPath, tmpO.imgsList ); 		
  },  
  
  ScrollImgs: function( n ) {  
    var cpos = this.slideEl.getPosition(this.thEl).x;
    var move = cpos - ( (this.thWidth + this.spics) * n );	
    var minx = -(((this.thWidth + this.spics) * this.imgs.length) - (this.options.width - 40)); 
    
    if (move > 0) move = 0;
    if (move < minx) move = minx;    
    var e = new Fx.Morph(this.slideEl, { duration: this.options.duration } );
    e.start( {'opacity': [1, .7], 'left':move} ).chain(      
      function(){ this.start( {'opacity': 1} ); }
    );        
  },
    
  SetImgsList: function( basePath, imgsName ) {    
    this.imgsPath = basePath;
    this.imgsList = imgsName;
    this.imgs     = null; 	  
 	  var imgsFiles = []; 	  
 	  var tmpO = this.options;

    this.slideEl.setStyles( {'opacity': 0} );
    this.slideEl.empty();
 	   	  
    this.ShowLoader( true );   
              
    for( n = 0; n < imgsName.length; n++ ) {   
      imgsFiles[n] = tmpO.phpThumbFile +'?width='+this.thWidth+ '&' +
                                         'height='+tmpO.height+ '&' +
                                         'src=' + basePath + '/' + imgsName[n].img;         
    }
    
    this.imgs = new Asset.images( imgsFiles, {
        onComplete: function() {         
          this.ImgRefresh();    
          this.ShowLoader( false );                                 
        }.bind( this )        
    });       
  },
  
  ImgRefresh: function() {
    var to = this.options;
    this.slideEl.setStyles( {'opacity': 0} );
    this.slideEl.empty();
              
    for( n = 0; n < this.imgs.length; n++ ) {
      var i = this.imgs[ n ]; 
      i.inject( this.slideEl );
      i.store('value', this.imgsList[n].value );
      i.store('img', this.imgsList[n].img );
      
      var sz = i.getSize();
      var my = (to.height - sz.y) / 2;
      var mx = (this.thWidth - sz.x - this.spics) / 2;                 
      i.setStyles( {'margin-left':mx,'margin-top':my,'margin-right':this.spics+mx} );            
          
      i.addEvent('click',  function( e ) { 
        e.stop;       
        this.fireEvent( "click", { 'img': e.target.retrieve('img'), 'value': e.target.retrieve('value') } );        
      }.bind( this ) );      
    }    
    this.slideEl.tween( 'opacity', 1 );    
  },
    
  ShowLoader: function( sts ) {
    // Contenitore base immagine
    if ( this.loaderEl != null ) this.loaderEl.destroy();
    if ( sts == false ) return;
          
    this.loaderEl = new Element('div', {  
      'class': 'loader',    
      'styles': { 
        'top': (this.options.height - 24) / 2, 
        'left':(this.options.width  - 64) / 2
      }
    }).inject( this.thEl );    
  },
  
  GetImgsPath: function() {
    return( this.imgsPath );
  }
     
});  

// =============================================================================
//  ImageMenu
// =============================================================================

var cfImageMenu = new Class({
	
  Implements: [Events, Options],

  options: { 
    left:0, top:0, 
    width:600, height:200,     
    imgsPath: './images',           // Base path immagini
    imgsList: null,                 // lista immagini
    imgSelectedWidth: 340,          // dimensione immagine selezionata 
    imgSpace: 5,                    // spazio orizzontale tra immagini
		duration: 400,                  // durata transizione 
    dClass:'cf-ImMe',   	
    // Events
    onClick: $empty				    
	},
	
  initialize: function( container, options ) {    	
		this.setOptions(options);
    var tmpO = this.options;		
  
  	this.container = container;		
			
    // Elemento Master
    this.imEl = new Element('div', {        
      'class': tmpO.dClass,     
      'styles': {'top': tmpO.top, 'left': tmpO.left, 'width': tmpO.width, 'height': tmpO.height}
    }).inject( container );
    						
		this.imgNum     = tmpO.imgsList.length;
		this.selWidth   = tmpO.imgSelectedWidth;
		this.norWidth   = ((tmpO.width + tmpO.imgSpace) / this.imgNum) - tmpO.imgSpace;
		this.unselWidth = ((tmpO.width - this.selWidth) / (this.imgNum - 1));
		this.els        = {};
		
    this.ul = new Element('ul', {
       'styles': { 'top':0, 
                   'left':0, 
                   'width':this.imgNum * (this.selWidth + tmpO.imgSpace), 
                   'height':tmpO.height 
                 }
    }).inject( this.imEl );    			
  
    for ( i = 0; i < this.imgNum; i++ ) {    
      var imgFileName = tmpO.imgsPath + '/' + tmpO.imgsList[i].img;
    
      this.els[i] = new Element('li', {        
        'styles': {
          'width':this.norWidth, 
          'height':tmpO.height, 
          'margin-right':((i == (this.imgNum-1) ) ? 0 : tmpO.imgSpace),
          'background': 'url(' + imgFileName + ') no-repeat'
        },
        'morph': {duration: tmpO.duration, transition: Fx.Transitions.Quad.easeIn},
        'events': { 'click': function(e) { e.stop; } }
      }).inject( this.ul ); 
      
      this.els[i].store('value', tmpO.imgsList[i].value );
      
      this.els[i].addEvents({
        'mouseenter': function(e) {
  				e.stop();				
          this.resetImages( e.target.retrieve('value') );				
  			}.bind(this),      
      
			  'mouseleave': function(e) {
  				e.stop();
	   			this.resetImages( '' );				
			  }.bind(this),
			  
			  'click': function(e) {     
          e.stop;          			    
			    this.fireEvent( "click", e.target.retrieve('value') );
			  }.bind(this)
      });     
    }  
  },
  
  resetImages: function( elVal ) {
    var w = this.norWidth;       
  
    for ( i = 0; i < this.imgNum; i++ ) {
      var e = this.els[i];      
      
      if (elVal != '') {              
        w = (e.retrieve('value') == elVal) ? this.selWidth : this.unselWidth;        
      } 
      e.morph( {'width': w } );
    }   
  }   
});

// =============================================================================
//  ImageGallery
// =============================================================================
	
var cfImageGallery = new Class({
	
  Implements: [Events, Options],

  options: { 
    left:0, 
    top:0, 
    width:600, 
    height:600,
    lheight:100, 
    nrPics:5,    
    imgsPath: './images',
    imgsList: null,
    fadeImg: 'normal',
    fadeList: 300,    
    phpThumbFile: 'cflibs/cf-image.php',
    // Events
    onImgChange: $empty
	},
	initialize: function( container, options ) {    	
		this.setOptions(options);
    var to = this.options;

    // Elemento Master
    this.elBase = new Element('div', {        
      'class': 'cf-ImGa',     
      'styles': {'top': to.top, 'left': to.left, 'width': to.width, 'height': to.height}
    }).inject( container );    
        
    this.elImg = new cfImage( this.elBase, {           
            width:to.width, 
            height:to.height - to.lheight,     
            imgPath: to.imgsPath,    
            imgFile: null,
            imgRef: null,
            phpThumbFile: to.phpThumbFile,
            onImgChange: function( v ) { this._onImgChanging( v ); }.bind( this )
    });    	
    
    this.elList = new cfImageList( this.elBase, {           
            width:to.width, 
            height: to.lheight,     
            imgsPath: to.imgsPath,            
            nrPics: to.nrPics,
            imgsPath: to.imgsPath,    
            imgsList: to.imgsList,
            phpThumbFile: to.phpThumbFile,
            onClick: function( v ) { this._onImgSelected( v ); }.bind( this )
    });        
  },
  
  _onImgChanging: function( v ) {
    this.fireEvent( "imgChange", v );
  },
  _onImgSelected: function( v ) {
    this.elImg.ShowImage( this.elList.GetImgsPath(), v.img, v.value );    
  }  
});

// =============================================================================
//  Shape
// =============================================================================
	
var cfShape = new Class({
	
  Implements: Options,

  options: { 
    left:0, 
    top:0, 
    width:400, 
    height:300,
    begin:[0,0],
    street: null,
    archsize: 10,
    background: '#0000ff',
    borderColor: '#00A2FF',
    borderSize: 1,
    contOffs:0   
	},
	
	initialize: function( container, options ) {    	
		this.setOptions(options);		
    var to  = this.options;    

    // Elemento Master
    this.elBase = new Element('div', {      
      'styles': {
        'position': 'relative',  
        'overflow': 'hidden',
	      'margin':0,
	      'padding':0,      
        'width': to.width,
        'height': to.height
      }     
    });
    
    if (Browser.Engine.trident) {    
      this.elC = new Element('canvas', {
        'class': 'cf-canvas',
        'width': to.width,
        'height':to.height
      }).inject( this.elBase );   
      
      // Trick getted from MochaUI, thanks Mocha!!!!    
			G_vmlCanvasManager.initElement( this.elC );
			this.elC = this.elBase.getElement('.cf-canvas');
		}         
    else {
      this.elBase.innerHTML = '<canvas width="' + to.width + 'px" height="' + to.height + 'px" class="cf-canvas"></canvas>';
      this.elC = this.elBase.getElement('.cf-canvas');
    }    
    
    ctx = this.elC.getContext('2d'); 
        
    ctx.fillStyle = to.background;
    ctx.lineWidth = to.borderSize;
    ctx.strokeStyle = to.borderColor; 

    this._drawShape( ctx, true );
    
    if (to.borderSize > 0) {
      this._drawShape( ctx, false );
    }
       
    this.elBase.inject( container.getParent() );
    this.elBase.wraps( container );    
    container.setStyles({'position':'absolute', 'left':to.contOffs,'top':to.contOffs});
  },  
  
  
  _drawShape: function( ctx, fill ) { 
    var to = this.options;
           
    ctx.beginPath();      
    
    // fissiamo il punto di partenza
    var t = [];          
    var l = to.begin;      
    ctx.moveTo(l[0], l[1]);  
    
    // iniziamo a seguire i punti
    for (i = 0; i < to.street.length; i++) {
      var s = to.street[i];
      
      if (s.drv == 'lineTo') {
        ctx.lineTo(s.xy[0], s.xy[1]);
        l = [s.xy[0], s.xy[1]];
      }
      else {
        t = this._CorrectPoints( l, s.xy, s.r );        
        ctx.lineTo(t[2], t[3]);
        
        var e = (i == (to.street.length - 1)) ? to.begin: to.street[i+1].xy;
        t = this._CorrectPoints( s.xy, e, s.r ); 
        ctx.quadraticCurveTo( s.xy[0], s.xy[1], t[0], t[1]);
        l = [t[0], t[1]];
      }
    }  
    if (fill) ctx.fill(); else ctx.stroke();    
  },
 
  _CorrectPoints: function(s, e, d) {    
    var dx = 0;
    var dy = 0;
    var ax = 1;
    var ay = 1;
    
    ax = (s[0] <= e[0]) ? 1 : -1;
    ay = (s[1] <= e[1]) ? 1 : -1;
    
    if (s[0] == e[0]) {       // Line is vertical
      dx = 0;
      dy = d * ay;
    }
    else if (s[1] == e[1]) {  // Line is horizzontal
      dx = d * ax;
      dy = 0;
    }
    else {                          // Other Lines
      var m = Math.atan( (e[1] - s[1]) / (e[0] - s[0]) );         
      dx = Math.round(Math.cos(m) * d) * ax;
      dy = Math.round(Math.sin(m) * d) * ay;      
    }      
    return( [s[0] + dx, s[1] + dy, e[0] - dx, e[1] - dy] );  
  }  
});