var userAgent = navigator.userAgent.toLowerCase();

// Figure out what browser is being used
jQuery.browser = {
	version: (userAgent.match( /.+(?:rv|it|ra|ie|me)[\/: ]([\d.]+)/ ) || [])[1],
	chrome: /chrome/.test( userAgent ),
	safari: /webkit/.test( userAgent ) && !/chrome/.test( userAgent ),
	opera: /opera/.test( userAgent ),
	msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
	mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
};

// SELETTORI CON NAMESPACE
/**
 * Il metodo ritorna l'elemento sul quale è chiamato se e solo se è contenuto nella stessa window dell'elemento
 * specificato dai parametri o è la window stessa window.
 * Se "type" è 'selector' allora "name" è il selettore dell'elemento
 * Se "type" è un carattere (default: '^', '*', '$') indica l'operatore da mettere prima dell'uguaglianza fra id e "name"
 */
$.fn.belongTo = function( name , type) {

    var selector = '';
    // name è selettore e type è 'selector'
    if (type == 'selector') {
        selector = name;
    // name è l'id e type è l'operatore prima dell'uguale
    } else {
        if (type === undefined) type = '^';
        type += '=';
        if (name.indexOf('application-') == 0){
            name = name.substring(12);
            if(name.indexOf('-') > 1){
                type = '$=';
            } else {
                type = '*=';
            }
            selector = 'div[id'+type+name+']:not([id^=admin])';
        } else {
            selector = 'div[id'+type+name+']';
        }
    }
    if (
        // body
        (this.selector == 'body' && this.find(selector).length > 0) ||
        // tag standard
        (this.selector && this.parents('body').find(selector).length > 0) ||
        // document
        (!this.selector && this[0].body && this.find(selector).length > 0) ||
        // window
        (!this.selector && this[0].document && $(this[0].document).find(selector).length > 0)
    )
        return this;
    else
        return $();
};

// BANNER
$.fn.epBanner = function(conf) {


    conf.container = this;


    return new $.epBanner(conf);

}

$.epBanner = function(conf) {
    this.fadeDuration = conf.fadeDuration || 1000;
    this.showDuration = conf.showDuration || 3000;
    this.height = conf.height || 100;
    this.width = conf.width || 100;
    this.current = 0;

    this.container = conf.container
    this.children = $(conf.container).children();
    this.childrenCount = this.children.length;

    this.timeoutId = null;

    var that = this;

    clearTimeout(this.timeoutId);

    $(conf.container).css({'overflow':'hidden', 'position':'relative'});
    $(conf.container).children().css({'overflow':'hidden', 'position':'absolute', 'top':0, 'left':0, 'display':'none'});
    $(conf.container).children('.selected').css('display','block');


    $(conf.container).css('height',that.height + 'px')
          .children().css('height',that.height + 'px');

    $(conf.container).css('width',that.width + 'px')
        .children().css('width',that.width + 'px');


    this.next = function() {
        clearTimeout(that.timeoutId);
        var tmp = that.current;
        that.current++;
        if(that.current>=that.childrenCount) that.current = 0;
        $(that.children[that.current]).fadeIn(that.fadeDuration);
        $(that.children[tmp]).fadeOut(that.fadeDuration);
        that.roll(that.next);
    };
    this.prev = function() {
        clearTimeout(that.timeoutId);
        var tmp = that.current
        that.current--;
        if(that.current<0) that.current = that.childrenCount-1;
        $(that.children[that.current]).fadeIn(that.fadeDuration);
        $(that.children[tmp]).fadeOut(that.fadeDuration);
        that.roll(that.prev);
    };

    this.roll = function(fn) {

        that.timeoutId = setTimeout(fn,that.showDuration);
    }

    this.stop = function() {
        clearTimeout(that.timeoutId);
    }

    $(conf.container).mouseenter(that.stop);
    $(conf.container).mouseleave(function(e) {
        if($(conf.container).children().size()>1)
            that.roll(that.next);
    });

    $(that.container).nextAll('.next_banner').click(that.next);
    $(that.container).nextAll('.prev_banner').click(that.prev);

    //verifico di avere piu' di un banner per effettuare la rotazione
    if($(conf.container).children().size()>1)
        this.roll(that.next);
}

// WATERMARK
$.fn.watermark = function(css, text) {
    return this.each(function() {
            var i = $(this), w;
            i.focus(function() {
                    w && !(w=0) && i.removeClass(css).data('w',0).val('');
            })
            .blur(function() {
                    !i.val() && (w=1) && i.addClass(css).data('w',1).val(text);
            })
            .closest('form').submit(function() {
                    w && i.val('');
            });
            i.blur();
    });
};

// CAROUSEL
/**
 * Creates a carousel for all matched elements.
 *
 * @example $("#mycarousel").jcarousel();
 * @before <ul id="mycarousel" class="jcarousel-skin-name"><li>First item</li><li>Second item</li></ul>
 * @result
 *
 * <div class="jcarousel-skin-name">
 *   <div class="jcarousel-container">
 *     <div class="jcarousel-clip">
 *       <ul class="jcarousel-list">
 *         <li class="jcarousel-item-1">First item</li>
 *         <li class="jcarousel-item-2">Second item</li>
 *       </ul>
 *     </div>
 *     <div disabled="disabled" class="jcarousel-prev jcarousel-prev-disabled"></div>
 *     <div class="jcarousel-next"></div>
 *   </div>
 * </div>
 *
 * @method jcarousel
 * @return jQuery
 * @param o {Hash|String} A set of key/value pairs to set as configuration properties or a method name to call on a formerly created instance.
 */
$.fn.jcarousel = function(o) {
    if (typeof o == 'string') {
        var instance = $(this).data('jcarousel'), args = Array.prototype.slice.call(arguments, 1);
        return instance[o].apply(instance, args);
    } else
        return this.each(function() {
            $(this).data('jcarousel', new $jc(this, o));
        });
};

/* AUTOCOMPLETER
 *   Associa a un campo di testo un autocompleter.
 */
$.fn.auto_completer = function(conf){
    conf.input_text = this;
    return new $.auto_completer(conf);
};

/* SLIDER
 *   Fa scorrere un elemento
 */
$.fn.get_slider = function(configuration){
    var conf = configuration || {};
    conf.container = $(this);
    return new $.slider(conf);
};

/**
 * Ajax upload
 * Project page - http://valums.com/ajax-upload/
 * Copyright (c) 2008 Andris Valums, http://valums.com
 * Licensed under the MIT license (http://valums.com/mit-license/)
 * Version 3.5 (23.06.2009)
 */

/**
 * Changes from the previous version:
 * 1. Added better JSON handling that allows to use 'application/javascript' as a response
 * 2. Added demo for usage with jQuery UI dialog
 * 3. Fixed IE "mixed content" issue when used with secure connections
 *
 * For the full changelog please visit:
 * http://valums.com/ajax-upload-changelog/
 */

$.fn.ajaxUpload = function(options) {
    return new AjaxUpload(this, options);
};

// PHOTOZOOM
/**
 *  Al click sull'oggetto agganciato a questa funzione, le immagini vengono visualizzate con lo zoom.
 *
 *  $('.imgBig img').photo_zoom({'name':'img_zoom', 'width':-300, 'scroll': 0});
 *
 *  INPUT: conf
 *
 *      oggetto con i campi:
 *
 *           name:    Valore dell'attributo "name" delle foto di cui fare lo zoom
 *                    Default: 'img_zoom'
 *
 *           width:   Larghezza dello zoom
 *                    Se negativa viene interpretata come dimensione da sottrarre alla larghezza dello schermo
 *                    Default: -300
 *
 *           scroll:  Se vero l'immagine può essere navigata con lo scroll della finestra
 *                    Se falso l'immagine può essere navigata con il movimento del mouse
 *                    Default: 0
 */

$.fn.photo_zoom = function(conf){
    return new $.photo_zoom(this,conf);
};


// *********************************************** PHOTOZOOM ***************************************************** //
$.photo_zoom = function(selector,conf){
    var name = conf.name;
    var img_width = conf.width;
    var default_scroll = conf.scroll;
    var margin = conf.margin;
    var max_height = $(window).height() + 50;
    var visible;

    if(!name) name = 'img_zoom';
    if(!img_width) img_width = -300;
    if(!default_scroll || default_scroll === 'false' || default_scroll === '0' || default_scroll === 'No' || default_scroll === 'NO' || default_scroll === 'no') default_scroll = 0;
    if(!margin) margin = 20;

    $('img[name='+name+']').each(function(i,el){
        if(el.src.indexOf('download.php') != -1){
            var image = el.src.replace(/(download.php).*fp=\//, "");
        } else {
            image = el.src.replace(/(\d)+x(\d)+\//,"");
        }
        $('body').append('<img class="img_zoom_'+name+'" style="display:none;position:absolute; z-index:99999;" src="'+image+'" />');
    });

    $('.img_zoom_'+name).each(function(i,el){
        if(max_height < $(el).height()){
            max_height = $(el).height();
        }
    });

    max_height = max_height+margin*2;

    $('body').append('<div id="hdbox_'+name+'" style="display:none;"></div>');

    $('#hdbox_'+name).css({
        'position':'fixed',
        'top':0,
        'left':0,
        'height': max_height + 50,
        'width':$(window).width() + 50,
        'z-index':10000,
        'background-color':'grey',
        'opacity':0.8
    });

    if($('img[name='+name+']').length > 1){
        $('body').append('<div class="hd_left_'+name+'" style="display:none;position:fixed;cursor:pointer;z-index:999999;"><img src="/images/hd_left.png" border="0" /></div>');
        $('body').append('<div class="hd_right_'+name+'" style="display:none;position:fixed;cursor:pointer;z-index:999999;"><img src="/images/hd_right.png" border="0" /></div>');
    }
    $('body').append('<div class="hd_close_'+name+'" style="display:none;position:fixed;cursor:pointer;z-index:999999;"><img src="/images/hd_x.png" border="0" /></div>');
    $('body').append('<div class="hd_scroll_'+name+'" style="display:none;position:fixed;cursor:pointer;z-index:999999;"><img src="/images/hd_scroll.png" border="0" title="Disattiva scroll con il mouse" /></div>');
    $('body').append('<div class="hd_no_scroll_'+name+'" style="display:none;position:fixed;cursor:pointer;z-index:999999;"><img src="/images/hd_no_scroll.png" border="0" title="Attiva scroll con il mouse" /></div>');

    $(selector).click(function(){
        if(this.src.indexOf('download.php') != -1){
            var src = this.src.replace(/(download.php).*fp=\//, "");
        } else {
            src = this.src.replace(/(\d)+x(\d)+\//,"");
        }
        $('html,body,.main').css({'height':max_height,'overflow':'scroll'});
        $('.current_photo').removeClass('current_photo');
        $('#hdbox_'+name+',.hd_close_'+name+',.hd_no_scroll_'+name).css('display','block');
        $('.hd_left_'+name+',.hd_right_'+name).fadeIn(1000);
        $('.img_zoom_'+name+'[src='+src+']').fadeIn(500).addClass('current_photo');
        setPosition();
        if(!default_scroll) $('.hd_no_scroll_'+name).trigger('click');
    });

    $('.hd_scroll_'+name).click(function(){
        var height = $(window).height() > $('.current_photo').height() ? $(window).height() : $('.current_photo').height();
        height += 50;
        $(this).hide();
        $('.hd_no_scroll_'+name).show();
        $('html,body,.main').css({'height':height,'overflow':'scroll'});
        $('#hdbox_'+name).css({'height': height,'overflow':''});
        $('#hdbox_'+name+',.img_zoom_'+name).unbind('mousemove');
        setPosition(-10);
    });

    $('.hd_no_scroll_'+name).click(function(){
        $(this).hide();
        $('.hd_scroll_'+name).show();
        $('html,body,.main,#hdbox_'+name).css({'height':$(window).height() + 50,'overflow':'hidden'});
        $('#hdbox_'+name+',.img_zoom_'+name).bind('mousemove',function(e){
            setScrollX(e);
            setScrollY(e);
        });
        setPosition();
    });

    $('.hd_close_'+name).click(function(){
        $('#hdbox_'+name+',.hd_left_'+name+',.hd_right_'+name+',.img_zoom_'+name+',.hd_close_'+name+',.hd_scroll_'+name+',.hd_no_scroll_'+name).css('display','none');
        $('html,body,.main').css({'height':'','overflow':''});
        $('#hdbox_'+name+',.img_zoom_'+name).unbind('mousemove');
    });

    $('.hd_left_'+name).click(function(){
        visible = $('.img_zoom_'+name+':visible');
        $('.current_photo').removeClass('current_photo');
        if(visible.prev('.img_zoom_'+name).length > 0){
            visible.prev('.img_zoom_'+name).fadeIn(500).addClass('current_photo');
        } else {
            $('.img_zoom_'+name+':last').fadeIn(500).addClass('current_photo');
        }
        setPosition();
        visible.fadeOut(500);
    });

    $('.hd_right_'+name).click(function(){
        visible = $('.img_zoom_'+name+':visible');
        $('.current_photo').removeClass('current_photo');
        if(visible.next('.img_zoom_'+name).length > 0){
            visible.next('.img_zoom_'+name).fadeIn(500).addClass('current_photo');
        } else {
            $('.img_zoom_'+name+':first').fadeIn(500).addClass('current_photo');
        }
        setPosition();
        visible.fadeOut(500);
    });

    $(window).resize(function(e) {
        $('#hdbox_'+name).css('height',$(window).height()).css('width',$(window).width());
        setPosition();
    });

    function setPosition(right){
        if(right === undefined) right = 0;
        var width,left;
        if(img_width > 0){
            width = img_width;
        } else {
            if($('.current_photo').width() > $(window).width()){
                width = $(window).width() + img_width;
            } else {
                width = $('.current_photo').width();
            }
        }
        if($(window).height() > $('.current_photo').height()){
            margin = ($(window).height() - $('.current_photo').height())/2;
        } else {
            margin = 20;
        }

        left = ($(window).width()-width)/2;
        $('.current_photo').css({'top':margin+'px','left':left+'px','width':width + 'px'});
        $('.hd_left_'+name).css({'top':$(window).height()/2+'px','left':'20px'});
        $('.hd_right_'+name).css({'top':$(window).height()/2+'px','right':(right+20)+'px'});
        $('.hd_close_'+name).css({'top':'20px','right':(right+20)+'px'});
        $('.hd_scroll_'+name+',.hd_no_scroll_'+name).css({'top':'20px','left':'20px'});
    }

    function setScrollX(e){
        var scroll_spread = $(document).scrollLeft();
        var m = (($('.img_zoom_'+name+':visible').width()-$('#hdbox_'+name).width()+10)/$('#hdbox_'+name).width());
        var posx = - (e.pageX - scroll_spread) * m;
        var hdimageXend = posx + $('.img_zoom_'+name+':visible').width() - scroll_spread;
        var hdboxXend = $('#hdbox_'+name).width();

        if(hdimageXend >=  (hdboxXend-scroll_spread)) {
            if(e.pageX < $(window).width()/2){
                $('.img_zoom_'+name+':visible').css('left',posx + margin);
            } else {
                $('.img_zoom_'+name+':visible').css('left',posx - margin);
            }
        }
    }

    function setScrollY(e){
        var scroll_spread = $(document).scrollTop();
        var m = (($('.img_zoom_'+name+':visible').height()-$('#hdbox_'+name).height()+10)/$('#hdbox_'+name).height());
        var posy = - (e.pageY - scroll_spread) * m;
        var hdimageYend = posy + $('.img_zoom_'+name+':visible').height() - scroll_spread;
        var hdboxYend = $('#hdbox_'+name).height();

        if(hdimageYend >=  (hdboxYend-scroll_spread)) {
            if(e.pageY < $(window).height()/2){
                $('.img_zoom_'+name+':visible').css('top',posy + margin);
            } else {
                $('.img_zoom_'+name+':visible').css('top',posy - margin);
            }
        }
    }
}
// ******************************************** FINE PHOTOZOOM ************************************************** //

// *********************************************** CAROUSEL ***************************************************** //

// Default configuration properties.
var defaults = {
    vertical: false,
    start: 1,
    offset: 1,
    size: null,
    scroll: 3,
    visible: null,
    animation: 'normal',
    easing: 'swing',
    auto: 0,
    wrap: null,
    initCallback: null,
    reloadCallback: null,
    itemLoadCallback: null,
    itemFirstInCallback: null,
    itemFirstOutCallback: null,
    itemLastInCallback: null,
    itemLastOutCallback: null,
    itemVisibleInCallback: null,
    itemVisibleOutCallback: null,
    buttonNextHTML: '<div></div>',
    buttonPrevHTML: '<div></div>',
    buttonNextEvent: 'click',
    buttonPrevEvent: 'click',
    buttonNextCallback: null,
    buttonPrevCallback: null
};

/**
 * The jCarousel object.
 *
 * @constructor
 * @class jcarousel
 * @param e {HTMLElement} The element to create the carousel for.
 * @param o {Object} A set of key/value pairs to set as configuration properties.
 * @cat Plugins/jCarousel
 */
$.jcarousel = function(e, o) {
    this.options    = $.extend({}, defaults, o || {});

    this.locked     = false;

    this.container  = null;
    this.clip       = null;
    this.list       = null;
    this.buttonNext = null;
    this.buttonPrev = null;


    this.wh = !this.options.vertical ? 'width' : 'height';
    this.lt = !this.options.vertical ? 'left' : 'top';

    // Extract skin class
    var skin = '', split = e.className.split(' ');

    for (var i = 0; i < split.length; i++) {
        if (split[i].indexOf('jcarousel-skin') != -1) {
            $(e).removeClass(split[i]);
            skin = split[i];
            break;
        }
    }

    if (e.nodeName == 'UL' || e.nodeName == 'OL') {
        this.list = $(e);
        this.container = this.list.parent();

        if (this.container.hasClass('jcarousel-clip')) {
            if (!this.container.parent().hasClass('jcarousel-container'))
                this.container = this.container.wrap('<div></div>');

            this.container = this.container.parent();
        } else if (!this.container.hasClass('jcarousel-container'))
            this.container = this.list.wrap('<div></div>').parent();
    } else {
        this.container = $(e);
        this.list = this.container.find('ul,ol').eq(0);
    }

    if (skin != '' && this.container.parent()[0].className.indexOf('jcarousel-skin') == -1)
        this.container.wrap('<div class=" '+ skin + '"></div>');

    this.clip = this.list.parent();

    if (!this.clip.length || !this.clip.hasClass('jcarousel-clip'))
        this.clip = this.list.wrap('<div></div>').parent();

    this.buttonNext = $('.jcarousel-next', this.container);

    if (this.buttonNext.size() == 0 && this.options.buttonNextHTML != null)
        this.buttonNext = this.clip.after(this.options.buttonNextHTML).next();

    this.buttonNext.addClass(this.className('jcarousel-next'));

    this.buttonPrev = $('.jcarousel-prev', this.container);

    if (this.buttonPrev.size() == 0 && this.options.buttonPrevHTML != null)
        this.buttonPrev = this.clip.after(this.options.buttonPrevHTML).next();

    this.buttonPrev.addClass(this.className('jcarousel-prev'));


    this.clip.addClass(this.className('jcarousel-clip')).css({
        overflow: 'hidden',
        position: 'relative'
    });
    this.list.addClass(this.className('jcarousel-list')).css({
        overflow: 'hidden',
        position: 'relative',
        top: 0,
        left: 0,
        margin: 0,
        padding: 0
    });
    this.container.addClass(this.className('jcarousel-container')).css({
        position: 'relative'
    });

    var di = this.options.visible != null ? Math.ceil(this.clipping() / this.options.visible) : null;
    var li = this.list.children('li');
    var self = this;

    if (li.size() > 0) {
        var wh = 0, i = this.options.offset;
        li.each(function() {
            self.format(this, i++);
            wh += self.dimension(this, di);
        });

        this.list.css(this.wh, wh + 'px');

        // Only set if not explicitly passed as option
        if (!o || o.size === undefined)
            this.options.size = li.size();
    }

    // For whatever reason, .show() does not work in Safari...
    this.container.css('display', 'block');
    this.item_width = o.item_width;
    this.item_height = o.item_height;
    // @author Leonardo - @since 02/04/2011
    // Tolto selettore principale .jcarousel-skin-tuttoverde visto che ho solo 1 carousel per problemi di multi application
    if($('#mycarousel > li').length <= 3){
        $('.jcarousel-next').css('display', 'none');
        $('.jcarousel-prev').css('display', 'none');
        // this.buttonNext.css('display', 'none');
        // this.buttonPrev.css('display', 'none');
        $('.jcarousel-container-vertical').css('padding', '0px 20px');
    }else {
        $('.jcarousel-prev').css('display', 'block');
        $('.jcarousel-prev').css('display', 'block');
    }


    this.funcNext   = function() {self.next();};
    this.funcPrev   = function() {self.prev();};
    this.funcResize = function() {self.reload();};

    if (this.options.initCallback != null)
        this.options.initCallback(this, 'init');

    if ($.browser.safari) {
        this.buttons(false, false);
        $(window).bind('load.jcarousel', function() {self.setup();});
    }else
        this.setup();
};

// Create shortcut for internal use
var $jc = $.jcarousel;

$jc.fn = $jc.prototype = {
    jcarousel: '0.2.4'
};

$jc.fn.extend = $jc.extend = $.extend;

$jc.fn.extend({
    /**
     * Setups the carousel.
     *
     * @method setup
     * @return undefined
     */
    setup: function() {
        this.first     = null;
        this.last      = null;
        this.prevFirst = null;
        this.prevLast  = null;
        this.animating = false;
        this.timer     = null;
        this.tail      = null;
        this.inTail    = false;

        if (this.locked)
            return;

        this.list.css(this.lt, this.pos(this.options.offset) + 'px');
        var p = this.pos(this.options.start);
        this.prevFirst = this.prevLast = null;
        this.animate(p, false);

        $(window).unbind('resize.jcarousel', this.funcResize).bind('resize.jcarousel', this.funcResize);
    },

    /**
     * Clears the list and resets the carousel.
     *
     * @method reset
     * @return undefined
     */
    reset: function() {
        this.list.empty();

        this.list.css(this.lt, '0px');
        this.list.css(this.wh, '10px');

        if (this.options.initCallback != null)
            this.options.initCallback(this, 'reset');

        this.setup();
    },

    /**
     * Reloads the carousel and adjusts positions.
     *
     * @method reload
     * @return undefined
     */
    reload: function() {
        if (this.tail != null && this.inTail)
            this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) + this.tail);

        this.tail   = null;
        this.inTail = false;

        if (this.options.reloadCallback != null)
            this.options.reloadCallback(this);

        if (this.options.visible != null) {
            var self = this;
            var di = Math.ceil(this.clipping() / this.options.visible), wh = 0, lt = 0;
            $('li', this.list).each(function(i) {
                wh += self.dimension(this, di);
                if (i + 1 < self.first)
                    lt = wh;
            });

            this.list.css(this.wh, wh + 'px');
            this.list.css(this.lt, -lt + 'px');
        }

        this.scroll(this.first, false);
    },

    /**
     * Locks the carousel.
     *
     * @method lock
     * @return undefined
     */
    lock: function() {
        this.locked = true;
        this.buttons();
    },

    /**
     * Unlocks the carousel.
     *
     * @method unlock
     * @return undefined
     */
    unlock: function() {
        this.locked = false;
        this.buttons();
    },

    /**
     * Sets the size of the carousel.
     *
     * @method size
     * @return undefined
     * @param s {Number} The size of the carousel.
     */
    size: function(s) {
        if (s != undefined) {
            this.options.size = s;
            if (!this.locked)
                this.buttons();
        }

        return this.options.size;
    },

    /**
     * Checks whether a list element exists for the given index (or index range).
     *
     * @method get
     * @return bool
     * @param i {Number} The index of the (first) element.
     * @param i2 {Number} The index of the last element.
     */
    has: function(i, i2) {
        if (i2 == undefined || !i2)
            i2 = i;

        if (this.options.size !== null && i2 > this.options.size)
            i2 = this.options.size;

        for (var j = i; j <= i2; j++) {
            var e = this.get(j);
            if (!e.length || e.hasClass('jcarousel-item-placeholder'))
                return false;
        }

        return true;
    },

    /**
     * Returns a jQuery object with list element for the given index.
     *
     * @method get
     * @return jQuery
     * @param i {Number} The index of the element.
     */
    get: function(i) {
        return $('.jcarousel-item-' + i, this.list);
    },

    /**
     * Adds an element for the given index to the list.
     * If the element already exists, it updates the inner html.
     * Returns the created element as jQuery object.
     *
     * @method add
     * @return jQuery
     * @param i {Number} The index of the element.
     * @param s {String} The innerHTML of the element.
     */
    add: function(i, s) {
        var e = this.get(i), old = 0, add = 0;

        if (e.length == 0) {
            var c, e = this.create(i), j = $jc.intval(i);
            while (c = this.get(--j)) {
                if (j <= 0 || c.length) {
                    j <= 0 ? this.list.prepend(e) : c.after(e);
                    break;
                }
            }
        } else
            old = this.dimension(e);

        e.removeClass(this.className('jcarousel-item-placeholder'));
        typeof s == 'string' ? e.html(s) : e.empty().append(s);

        var di = this.options.visible != null ? Math.ceil(this.clipping() / this.options.visible) : null;
        var wh = this.dimension(e, di) - old;

        if (i > 0 && i < this.first)
            this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) - wh + 'px');

        this.list.css(this.wh, $jc.intval(this.list.css(this.wh)) + wh + 'px');

        return e;
    },

    /**
     * Removes an element for the given index from the list.
     *
     * @method remove
     * @return undefined
     * @param i {Number} The index of the element.
     */
    remove: function(i) {
        var e = this.get(i);

        // Check if item exists and is not currently visible
        if (!e.length || (i >= this.first && i <= this.last))
            return;

        var d = this.dimension(e);

        if (i < this.first)
            this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) + d + 'px');

        e.remove();

        this.list.css(this.wh, $jc.intval(this.list.css(this.wh)) - d + 'px');
    },

    /**
     * Moves the carousel forwards.
     *
     * @method next
     * @return undefined
     */
    next: function() {

        this.stopAuto();

        if (this.tail != null && !this.inTail)
            this.scrollTail(false);
        else
            this.scroll(((this.options.wrap == 'both' || this.options.wrap == 'last') && this.options.size != null && this.last == this.options.size) ? 1 : this.first + this.options.scroll);
    },

    /**
     * Moves the carousel backwards.
     *
     * @method prev
     * @return undefined
     */
    prev: function() {
        this.stopAuto();

        if (this.tail != null && this.inTail)
            this.scrollTail(true);
        else
            this.scroll(((this.options.wrap == 'both' || this.options.wrap == 'first') && this.options.size != null && this.first == 1) ? this.options.size : this.first - this.options.scroll);
    },

    /**
     * Scrolls the tail of the carousel.
     *
     * @method scrollTail
     * @return undefined
     * @param b {Boolean} Whether scroll the tail back or forward.
     */
    scrollTail: function(b) {
        if (this.locked || this.animating || !this.tail)
            return;

        var pos  = $jc.intval(this.list.css(this.lt));

        !b ? pos -= this.tail : pos += this.tail;
        this.inTail = !b;

        // Save for callbacks
        this.prevFirst = this.first;
        this.prevLast  = this.last;

        this.animate(pos);
    },

    /**
     * Scrolls the carousel to a certain position.
     *
     * @method scroll
     * @return undefined
     * @param i {Number} The index of the element to scoll to.
     * @param a {Boolean} Flag indicating whether to perform animation.
     */
    scroll: function(i, a) {
        if (this.locked || this.animating)
            return;

        this.animate(this.pos(i), a);
    },

    /**
     * Prepares the carousel and return the position for a certian index.
     *
     * @method pos
     * @return {Number}
     * @param i {Number} The index of the element to scoll to.
     */
    pos: function(i) {
        var pos  = $jc.intval(this.list.css(this.lt));

        if (this.locked || this.animating)
            return pos;

        if (this.options.wrap != 'circular')
            i = i < 1 ? 1 : (this.options.size && i > this.options.size ? this.options.size : i);

        var back = this.first > i;

        // Create placeholders, new list width/height
        // and new list position
        var f = this.options.wrap != 'circular' && this.first <= 1 ? 1 : this.first;
        var c = back ? this.get(f) : this.get(this.last);
        var j = back ? f : f - 1;
        var e = null, l = 0, p = false, d = 0, g;

        while (back ? --j >= i : ++j < i) {
            e = this.get(j);
            p = !e.length;
            if (e.length == 0) {
                e = this.create(j).addClass(this.className('jcarousel-item-placeholder'));
                c[back ? 'before' : 'after' ](e);

                if (this.first != null && this.options.wrap == 'circular' && this.options.size !== null && (j <= 0 || j > this.options.size)) {
                    g = this.get(this.index(j));
                    if (g.length)
                        this.add(j, g.children().clone(true));
                }
            }

            c = e;
            d = this.dimension(e);

            if (p)
                l += d;

            if (this.first != null && (this.options.wrap == 'circular' || (j >= 1 && (this.options.size == null || j <= this.options.size))))
                pos = back ? pos + d : pos - d;
        }

        // Calculate visible items
        var clipping = this.clipping();
        var cache = [];
        var visible = 0, j = i, v = 0;
        var c = this.get(i - 1);
        while (++visible) {
            e = this.get(j);
            p = !e.length;
            if (e.length == 0) {
                e = this.create(j).addClass(this.className('jcarousel-item-placeholder'));
                e.width(this.item_width);
                e.height(this.item_height);
                // This should only happen on a next scroll
                c.length == 0 ? this.list.prepend(e) : c[back ? 'before' : 'after' ](e);

                if (this.first != null && this.options.wrap == 'circular' && this.options.size !== null && (j <= 0 || j > this.options.size)) {
                    g = this.get(this.index(j));
                    if (g.length){
                        //aggiungo un elemento
                        this.add(j, g.find('>*').clone(true));
                        //rimuovo
                    }
                }
            }

            c = e;
            var d = this.dimension(e);
            if (d == 0) {
                //alert('jCarousel: No width/height set for items. This will cause an infinite loop. Aborting...');
                return 0;
            }

            if (this.options.wrap != 'circular' && this.options.size !== null && j > this.options.size)
                cache.push(e);
            else if (p)
                l += d;

            v += d;

            if (v >= clipping)
                break;

            j++;
        }

         // Remove out-of-range placeholders
        for (var x = 0; x < cache.length; x++)
            cache[x].remove();

        // Resize list
        if (l > 0) {
            this.list.css(this.wh, this.dimension(this.list) + l + 'px');

            if (back) {
                pos -= l;
                this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) - l + 'px');
            }
        }

        // Calculate first and last item
        var last = i + visible - 1;
        if (this.options.wrap != 'circular' && this.options.size && last > this.options.size)
            last = this.options.size;

        if (j > last) {
            visible = 0, j = last, v = 0;
            while (++visible) {
                var e = this.get(j--);
                if (!e.length)
                    break;
                v += this.dimension(e);
                if (v >= clipping)
                    break;
            }
        }

        var first = last - visible + 1;
        if (this.options.wrap != 'circular' && first < 1)
            first = 1;

        if (this.inTail && back) {
            pos += this.tail;
            this.inTail = false;
        }

        this.tail = null;
        if (this.options.wrap != 'circular' && last == this.options.size && (last - visible + 1) >= 1) {
            var m = $jc.margin(this.get(last), !this.options.vertical ? 'marginRight' : 'marginBottom');
            if ((v - m) > clipping)
                this.tail = v - clipping - m;
        }

        // Adjust position
        while (i-- > first)
            pos += this.dimension(this.get(i));

        // Save visible item range
        this.prevFirst = this.first;
        this.prevLast  = this.last;
        this.first     = first;
        this.last      = last;

        return pos;
    },

    /**
     * Animates the carousel to a certain position.
     *
     * @method animate
     * @return undefined
     * @param p {Number} Position to scroll to.
     * @param a {Boolean} Flag indicating whether to perform animation.
     */
    animate: function(p, a) {
        if (this.locked || this.animating)
            return;

        this.animating = true;

        var self = this;
        var scrolled = function() {
            self.animating = false;

            if (p == 0)
                self.list.css(self.lt,  0);

            if (self.options.wrap == 'circular' || self.options.wrap == 'both' || self.options.wrap == 'last' || self.options.size == null || self.last < self.options.size)
                self.startAuto();

            self.buttons();
            self.notify('onAfterAnimation');
        };

        this.notify('onBeforeAnimation');

        // Animate
        if (!this.options.animation || a == false) {
            this.list.css(this.lt, p + 'px');
            scrolled();
        } else {
            var o = !this.options.vertical ? {'left': p} : {'top': p};
            this.list.animate(o, this.options.animation, this.options.easing, scrolled);
        }
    },

    /**
     * Starts autoscrolling.
     *
     * @method auto
     * @return undefined
     * @param s {Number} Seconds to periodically autoscroll the content.
     */
    startAuto: function(s) {
        if (s != undefined)
            this.options.auto = s;

        if (this.options.auto == 0)
            return this.stopAuto();

        if (this.timer != null)
            return;

        var self = this;
        this.timer = setTimeout(function() {self.next();}, this.options.auto * 1000);
    },

    /**
     * Stops autoscrolling.
     *
     * @method stopAuto
     * @return undefined
     */
    stopAuto: function() {
        if (this.timer == null)
            return;

        clearTimeout(this.timer);
        this.timer = null;
    },

    /**
     * Sets the states of the prev/next buttons.
     *
     * @method buttons
     * @return undefined
     */
    buttons: function(n, p) {
        if (n == undefined || n == null) {
            var n = !this.locked && this.options.size !== 0 && ((this.options.wrap && this.options.wrap != 'first') || this.options.size == null || this.last < this.options.size);
            if (!this.locked && (!this.options.wrap || this.options.wrap == 'first') && this.options.size != null && this.last >= this.options.size)
                n = this.tail != null && !this.inTail;
        }

        if (p == undefined || p == null) {
            var p = !this.locked && this.options.size !== 0 && ((this.options.wrap && this.options.wrap != 'last') || this.first > 1);
            if (!this.locked && (!this.options.wrap || this.options.wrap == 'last') && this.options.size != null && this.first == 1)
                p = this.tail != null && this.inTail;
        }

        var self = this;

        this.buttonNext[n ? 'bind' : 'unbind'](this.options.buttonNextEvent + '.jcarousel', this.funcNext)[n ? 'removeClass' : 'addClass'](this.className('jcarousel-next-disabled')).attr('disabled', n ? false : true);
        this.buttonPrev[p ? 'bind' : 'unbind'](this.options.buttonPrevEvent + '.jcarousel', this.funcPrev)[p ? 'removeClass' : 'addClass'](this.className('jcarousel-prev-disabled')).attr('disabled', p ? false : true);

        if (this.buttonNext.length > 0 && (this.buttonNext[0].jcarouselstate == undefined || this.buttonNext[0].jcarouselstate != n) && this.options.buttonNextCallback != null) {
            this.buttonNext.each(function() {self.options.buttonNextCallback(self, this, n);});
            this.buttonNext[0].jcarouselstate = n;
        }

        if (this.buttonPrev.length > 0 && (this.buttonPrev[0].jcarouselstate == undefined || this.buttonPrev[0].jcarouselstate != p) && this.options.buttonPrevCallback != null) {
            this.buttonPrev.each(function() {self.options.buttonPrevCallback(self, this, p);});
            this.buttonPrev[0].jcarouselstate = p;
        }
    },

    /**
     * Notify callback of a specified event.
     *
     * @method notify
     * @return undefined
     * @param evt {String} The event name
     */
    notify: function(evt) {
        var state = this.prevFirst == null ? 'init' : (this.prevFirst < this.first ? 'next' : 'prev');

        // Load items
        this.callback('itemLoadCallback', evt, state);

        if (this.prevFirst !== this.first) {
            this.callback('itemFirstInCallback', evt, state, this.first);
            this.callback('itemFirstOutCallback', evt, state, this.prevFirst);
        }

        if (this.prevLast !== this.last) {
            this.callback('itemLastInCallback', evt, state, this.last);
            this.callback('itemLastOutCallback', evt, state, this.prevLast);
        }

        this.callback('itemVisibleInCallback', evt, state, this.first, this.last, this.prevFirst, this.prevLast);
        this.callback('itemVisibleOutCallback', evt, state, this.prevFirst, this.prevLast, this.first, this.last);
    },

    callback: function(cb, evt, state, i1, i2, i3, i4) {
        if (this.options[cb] == undefined || (typeof this.options[cb] != 'object' && evt != 'onAfterAnimation'))
            return;

        var callback = typeof this.options[cb] == 'object' ? this.options[cb][evt] : this.options[cb];

        if (!$.isFunction(callback))
            return;

        var self = this;

        if (i1 === undefined)
            callback(self, state, evt);
        else if (i2 === undefined)
            this.get(i1).each(function() {callback(self, this, i1, state, evt);});
        else {
            for (var i = i1; i <= i2; i++)
                if (i !== null && !(i >= i3 && i <= i4))
                    this.get(i).each(function() {callback(self, this, i, state, evt);});
        }
    },

    create: function(i) {
        return this.format('<li></li>', i);
    },

    format: function(e, i) {
        var $e = $(e).addClass(this.className('jcarousel-item')).addClass(this.className('jcarousel-item-' + i)).css({
            'float': 'left',
            'list-style': 'none'
        });
        $e.attr('jcarouselindex', i);
        return $e;
    },

    className: function(c) {
        return c + ' ' + c + (!this.options.vertical ? '-horizontal' : '-vertical');
    },

    dimension: function(e, d) {
        var el = e.jquery != undefined ? e[0] : e;

        var old = !this.options.vertical ?
            el.offsetWidth + $jc.margin(el, 'marginLeft') + $jc.margin(el, 'marginRight') :
            el.offsetHeight + $jc.margin(el, 'marginTop') + $jc.margin(el, 'marginBottom');

        if (d == undefined || old == d)
            return old;

        var w = !this.options.vertical ?
            d - $jc.margin(el, 'marginLeft') - $jc.margin(el, 'marginRight') :
            d - $jc.margin(el, 'marginTop') - $jc.margin(el, 'marginBottom');

        $(el).css(this.wh, w + 'px');

        return this.dimension(el);
    },

    clipping: function() {
        return !this.options.vertical ?
            this.clip[0].offsetWidth - $jc.intval(this.clip.css('borderLeftWidth')) - $jc.intval(this.clip.css('borderRightWidth')) :
            this.clip[0].offsetHeight - $jc.intval(this.clip.css('borderTopWidth')) - $jc.intval(this.clip.css('borderBottomWidth'));
    },

    index: function(i, s) {
        if (s == undefined)
            s = this.options.size;

        return Math.round((((i-1) / s) - Math.floor((i-1) / s)) * s) + 1;
    }
});

$jc.extend({
    /**
     * Gets/Sets the global default configuration properties.
     *
     * @method defaults
     * @return {Object}
     * @param d {Object} A set of key/value pairs to set as configuration properties.
     */
    defaults: function(d) {
        return $.extend(defaults, d || {});
    },

    margin: function(e, p) {
        if (!e)
            return 0;

        var el = e.jquery != undefined ? e[0] : e;

        if (p == 'marginRight' && $.browser.safari) {
            var old = {'display': 'block', 'float': 'none', 'width': 'auto'}, oWidth, oWidth2;

            $.swap(el, old, function() {oWidth = el.offsetWidth;});

            old['marginRight'] = 0;
            $.swap(el, old, function() {oWidth2 = el.offsetWidth;});

            return oWidth2 - oWidth;
        }

        return $jc.intval($.css(el, p));
    },

    intval: function(v) {
        v = parseInt(v);
        return isNaN(v) ? 0 : v;
    }
});

// ********************************************* FINE CAROUSEL ************************************************** //



// ********************************************* AUTOCOMPLETER ************************************************** //
/*
    Associa a un campo di testo un autocompleter.
   **************************************************************************************************************
    ESEMPIO:

    init = function(str){
        var jdata;
        $.ajax({
            async: false,    /////////////////////////////////// IMPORTANTISSIMO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
            method: 'post',
            url: '/admin/genpage-getNations?str='+str,
            success: function(data) {
                jdata = $.parseJSON(data);
                //$('input[name=id_nation]').data("data",jdata);
            }
        })
        return jdata;
    }

    operation = function(param){
        $('input[name=id_nation]').val(param[0]);
    }

    $('selettore campo di testo').auto_completer({
        'get_data':init,
        'id_field':["id_nation"],
        'search_field':["nation"],
        'operation':operation,
        'operation_args':["id_nation"],
        'type':'repeat_ajax',
        'min_char':0,
        'max_suggestion':6,
        'wait_time':1000
    });
   **************************************************************************************************************
    get_data : oggetto json con i dati nel campo resp oppure una funzione che restituisce tale oggetto (LA CHIAMATA AJAX DEVE ESSERE SINCRONA !!!!!!!!!!!!!!!!!!!!!!!)
   **************************************************************************************************************
    id_field : nome del campo che viene utilizzato come chiave nel campo resp
   **************************************************************************************************************
    search_field : array con i nomi dei campi presenti nel campo resp dell'oggetto json in cui cercare la stringa digitata nel campo di testo
   **************************************************************************************************************
    operation : funzione che viene eseguita alla selezione di uno dei suggerimenti visualizzati. In ingresso può prendere solo un array
                contenente i valori dei campi, definiti nel parametro operation_args, relativi al suggerimento selezionato.
   **************************************************************************************************************
    operation_args : vuole un array con i nomi dei campi ( dell'oggetto salvato dalla funzione data() )
                    da passare alla funzione operation
   **************************************************************************************************************
    type : se settato a 'repeat_ajax' allora l'input get_data deve essere una funzione, in quanto verrà richiamata ogni volta che cambia la stringa di ricerca
   **************************************************************************************************************
    min_char : numero minimo di caratteri per cui fare la ricerca   (DEFAULT 0)
   **************************************************************************************************************
    max_suggestion : numero massimo di suggerimenti stampati   (DEFAULT 6)
   **************************************************************************************************************
    wait_time : numero di millisecondi che aspetta prima di effettuare la ricerca   (DEFAULT 300)
   **************************************************************************************************************
    string_color : colore dello sfondo della stringa trovata   (DEFAULT '#55acdd')
   **************************************************************************************************************
    background_color : colore dello sfondo della stringa quando si effettua l'hover (DEFAULT '#55acdd')
   **************************************************************************************************************
*/
$.auto_completer = function(conf){

    /* **************************************** CONTROLLI **************************************** */

    var auto_completer = this;
    var timeout,obj;

    // Controlla che il primo parametro sia il selettore di un campo di testo
    if($(conf.input_text).get().length == 1 && $(conf.input_text).attr('type') == 'text' && ($.isFunction(conf.get_data) || conf.get_data.resp) ){
        this.input_text = conf.input_text;
        this.get_data = conf.get_data;
        this.id_field = conf.id_field;
        this.search_field = conf.search_field;
        if($.isFunction(conf.operation)){
            this.operation = conf.operation;
            this.operation_args = conf.operation_args;
        } else {
            this.operation = function(){
                $(auto_completer.input_text).val($(".auto_completer_selected").text());
            }
            this.operation_args = "default";
        }
        this.type = conf.type;
        if(this.type == 'repeat_ajax' && !$.isFunction(conf.get_data)) return false;
        this.min_char = conf.min_char || 0;
        this.max_suggestion = conf.max_suggestion || 6;
        this.wait_time = (conf.wait_time ? conf.wait_time : (conf.wait_time === 0 ? 0 : 300));
        this.string_color = conf.string_color || '#55acdd';
        this.background_color = conf.string_color || '#55acdd';
    } else {
        return false;
    }
    //console.log(auto_completer);
    $(auto_completer.input_text).unbind();
    $(auto_completer.input_text).die();
    $("#auto_completer_suggestion").remove();
    $("#auto_completer_suggestion").unbind();
    $("#auto_completer_suggestion a").die();
    $("#auto_completer_suggestion *").unbind();

    /* ************************************* FINE CONTROLLI ************************************** */

    // La classe .auto_completer_selected indica quale elemento creato dall'autocomplete è selezionato al momento (sfondo azzurro)
    $(".auto_completer_selected").css("background-color","");
    $(".auto_completer_selected").removeClass("auto_completer_selected");
    $(auto_completer.input_text).blur();


    // Associa il div che conterrà i suggerimenti e l'immagine da visualizzare durante l'attesa al campo di testo
    var mydiv = $("<div id='auto_completer_suggestion'></div>");

    // Rimuove i suggerimenti in caso di perdita del focus
    $(document).click(function(){
        $(".auto_completer_selected").css("background-color","");
        $(".auto_completer_selected").removeClass("auto_completer_selected");
        $("#auto_completer_suggestion a").remove();
        $("#auto_completer_suggestion").css({"border":"","overflow-y":"auto"});
    });

    // Quando il campo di testo ottiene il focus salva l'oggetto da cui ottenere i dati
    $(auto_completer.input_text).focus(function(){
        $(auto_completer.input_text).val("");
        if(auto_completer.type != 'repeat_ajax'){
            if(!auto_completer.get_data.resp){
                obj = auto_completer.get_data();
            } else {
                obj = auto_completer.get_data;
            }
        }
        //console.log(obj);
    });

    // Associa la classe .auto_completer_selected al suggerimento su cui il mouse è sopra
    $("#auto_completer_suggestion a").live('mouseover',function(){
        $(".auto_completer_selected").css("background-color","");
        $(".auto_completer_selected").removeClass("auto_completer_selected");
        $(this).addClass("auto_completer_selected");
        $(".auto_completer_selected").css("background-color",auto_completer.background_color);
    });

    // Rimuove la classe .auto_completer_selected al suggerimento da cui il mouse è uscito
    $("#auto_completer_suggestion a").live('mouseout',function(){
        $(".auto_completer_selected").css("background-color","");
        $(".auto_completer_selected").removeClass("auto_completer_selected");
    });

    // In risposta all'evento click esegue this.operation
    $("#auto_completer_suggestion a").live('click',function(e){
        e.preventDefault();
        if(!$('.auto_completer_selected')){
            return;
        }
        if(auto_completer.operation_args == "default"){
            auto_completer.operation();
        } else {
            var param = [];
            // Recupera i parametri specificati in this.operation_args
            for(var i in auto_completer.operation_args){
                param[i] = obj.resp[this.name][auto_completer.operation_args[i]];
            }
            auto_completer.operation(param);
        }
        $("#auto_completer_suggestion").css({"border":"","overflow-y":"auto","display":"none"});
        $("#auto_completer_suggestion a").remove();
        $(auto_completer.input_text).blur();
    });

    // Ricerca suggerimenti
    $(auto_completer.input_text).keyup(function(event){
        var key = event.which;
        if(key == 9 || key == 13 || key == 37 || key == 38 || key == 39 || key == 40){
            return;
        } else if(auto_completer.input_text.val().length <= auto_completer.min_char){
            clearTimeout(timeout);
            timeout = '';
            auto_completer.do_on_keyup();
        }
        clearTimeout(timeout);
        timeout = '';
        timeout = setTimeout(auto_completer.do_on_keyup,auto_completer.wait_time);
    });

    // Permette di scorrere i suggerimenti con le frecce e di stamparne i dati con il tasto invio
    $(auto_completer.input_text).keydown(function(event){
        if(timeout != ''){
            return;
        }
        // Se non ci sono suggerimenti esce
        if($("#auto_completer_suggestion a").length>0){
            var key = event.which;
            var index = $(".auto_completer_selected").index("#auto_completer_suggestion a");
            if(key==40 && $("#auto_completer_suggestion a").length == 1){
                $("#auto_completer_suggestion a").addClass("auto_completer_selected");
                $(".auto_completer_selected").css("background-color",auto_completer.background_color);
            // Se il tasto premuto è freccia in giù e non è l'ultimo elemento tra i suggerimenti
            // associa la classe .auto_completer_selected al suggerimento successivo
            } else if(key==40 && index<$("#auto_completer_suggestion a").length-1){
                if(index==-1){
                    $("#auto_completer_suggestion a").eq(0).addClass("auto_completer_selected");
                    $(".auto_completer_selected").css("background-color",auto_completer.background_color);
                } else {
                    $(".auto_completer_selected").css("background-color","");
                    $("#auto_completer_suggestion a").eq(index).removeClass("auto_completer_selected");
                    $("#auto_completer_suggestion a").eq(++index).addClass("auto_completer_selected");
                    $(".auto_completer_selected").css("background-color",auto_completer.background_color);
                }
                // Se il tasto premuto è freccia in su associa la classe .auto_completer_selected al suggerimento precedente
            } else if(key==38){
                $(".auto_completer_selected").css("background-color","");
                $("#auto_completer_suggestion a").eq(index).removeClass("auto_completer_selected");
                if(index>0){
                    $("#auto_completer_suggestion a").eq(--index).addClass("auto_completer_selected");
                    $(".auto_completer_selected").css("background-color",auto_completer.background_color);
                }
                // Se il tasto premuto è invio lancia l'evento "click" sull'elemento con classe .auto_completer_selected
            } else if(key==13){
                event.preventDefault();
                $(".auto_completer_selected").focus().trigger('click');
            } else if(key==9){
                event.preventDefault();
            }
        }
    });

    auto_completer.positioning = function(mydiv){
        // Recupera posizione e altezza del campo di testo a cui associare l'autocomplete
        var offset = $(auto_completer.input_text).offset();
        var width = $(auto_completer.input_text).outerWidth()-2;
        var height = $(auto_completer.input_text).outerHeight();

        // Associa il div che conterrà i suggerimenti e l'immagine da visualizzare durante l'attesa al campo di testo
        if($('#auto_completer_suggestion').length == 0){
            $(mydiv).appendTo('body');
        }
        $("#auto_completer_suggestion").css({"position":"absolute","top":offset.top+height,"left":offset.left,"width":width,"background-color": "white"});
    }

    auto_completer.do_on_keyup = function(){
        var count = 0;
        auto_completer.positioning(mydiv);
        timeout = '';

        // Se la stringa contenuta nel campo di testo è vuota cancella i suggerimenti
        if($(auto_completer.input_text).val().length > auto_completer.min_char){
            var str = $(auto_completer.input_text).val();
            if(str != mydiv.attr('name')){
                // Recupera oggetto
                if(auto_completer.type == 'repeat_ajax'){
                    obj = auto_completer.get_data(str);
                }
                mydiv.attr('name',str);
            }

            // Rimuove vecchi suggerimenti
            $("#auto_completer_suggestion a").remove();
            $("#auto_completer_suggestion").css({"border":"","overflow-y":"auto"});

            // Visualizza nuovi suggerimenti evidenziando la parte di nome che corrisponde alla stringa del campo di testo
            $.each(obj.resp,function(i,el){
                if(count == auto_completer.max_suggestion){
                    return;
                }
                var mystrU = "";
                for(i in auto_completer.search_field){
                    if(i < auto_completer.search_field.length-1){
                        mystrU = mystrU + el[auto_completer.search_field[i]] + " - ";
                    } else {
                        mystrU = mystrU + el[auto_completer.search_field[i]];
                    }

                }
                var mystr = mystrU;
                mystrU = mystrU.toUpperCase();
                var strU = str.toUpperCase();
                var start = mystrU.indexOf(strU);
                var end = start + str.length;
                if(start >= 0){
                    count++;
                    var tmp;
                    if(str == ' '){
                    } else {
                        mystr = mystr.slice(0,start) + '<span style="background-color:' + auto_completer.string_color + '">' + mystr.slice(start,end) + '</span>' + mystr.slice(end);
                    }
                    tmp = $('<a name="'+el[auto_completer.id_field]+'" style="display:block;overflow:hidden;cursor:default;color:#000000">' + mystr + '</a>');
                    $('#auto_completer_suggestion').append(tmp);
                }
            });

            // Se sono presenti suggerimenti gli associa degli handler per gestirne gli eventi
            if($("#auto_completer_suggestion a").length > 0)
                $("#auto_completer_suggestion").css({"border":"1px solid black","height":"auto","max-height":"150px","background-color":"white","display":"block"});

        } else {
            $("#auto_completer_suggestion").css({"border":"","overflow-y":"auto","display":"none"});
            $("#auto_completer_suggestion a").remove();
        }
    }

}

// ****************************************** FINE AUTOCOMPLETER ************************************************ //


// ********************************************** AJAXUPLOAD **************************************************** //


/**
 * Get element by id
 */
function ajax_upload_get(element){
	if (typeof element == "string")
		element = document.getElementById(element);
	return element;
}

/**
 * Attaches event to a dom element
 */
function ajax_upload_addEvent(el, type, fn){
	if(el != null){
		if (window.addEventListener){
			el.addEventListener(type, fn, false);
		} else if (window.attachEvent){
			var f = function(){
			  fn.call(el, window.event);
			};
			el.attachEvent('on' + type, f)
		}
	}
}

/**
 * Creates and returns element from html chunk
 */
var ajax_upload_toElement = function(){
	var div = document.createElement('div');
	return function(html){
		div.innerHTML = html;
		var el = div.childNodes[0];
		div.removeChild(el);
		return el;
	}
}();

function ajax_upload_hasClass(ele,cls){
	return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
}
function ajax_upload_addClass(ele,cls) {
	if (!ajax_upload_hasClass(ele,cls)) ele.className += " "+cls;
}
function ajax_upload_removeClass(ele,cls) {
	var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
	ele.className=ele.className.replace(reg,' ');
}

// getOffset function copied from jQuery lib (http://jquery.com/)
if (document.documentElement["getBoundingClientRect"]){
	// Get Offset using getBoundingClientRect
	// http://ejohn.org/blog/getboundingclientrect-is-awesome/
	var ajax_upload_getOffset = function(el){
		var box = el.getBoundingClientRect(),
		doc = el.ownerDocument,
		body = doc.body,
		docElem = doc.documentElement,

		// for ie
		clientTop = docElem.clientTop || body.clientTop || 0,
		clientLeft = docElem.clientLeft || body.clientLeft || 0,

		// In Internet Explorer 7 getBoundingClientRect property is treated as physical,
		// while others are logical. Make all logical, like in IE8.


		zoom = 1;
		if (body.getBoundingClientRect) {
			var bound = body.getBoundingClientRect();
			zoom = (bound.right - bound.left)/body.clientWidth;
		}
		if (zoom > 1){
			clientTop = 0;
			clientLeft = 0;
		}
		var top = box.top/zoom + (window.pageYOffset || docElem && docElem.scrollTop/zoom || body.scrollTop/zoom) - clientTop,
		left = box.left/zoom + (window.pageXOffset|| docElem && docElem.scrollLeft/zoom || body.scrollLeft/zoom) - clientLeft;

		return {
			top: top,
			left: left
		};
	}

} else {
	// Get offset adding all offsets
	ajax_upload_getOffset = function(el){
		if (window.jQuery){
			return jQuery(el).offset();
		}

		var top = 0, left = 0;
		do {
			top += el.offsetTop || 0;
			left += el.offsetLeft || 0;
		}
		while (el = el.offsetParent);

		return {
			left: left,
			top: top
		};
	}
}

function ajax_upload_getBox(el){
	var left, right, top, bottom;
	var offset = ajax_upload_getOffset(el);
	left = offset.left;
	top = offset.top;

	right = left + el.offsetWidth;
	bottom = top + el.offsetHeight;

	return {
		left: left,
		right: right,
		top: top,
		bottom: bottom
	};
}

/**
 * Crossbrowser mouse coordinates
 */
function ajax_upload_getMouseCoords(e){
	// pageX/Y is not supported in IE
	// http://www.quirksmode.org/dom/w3c_cssom.html
	if (!e.pageX && e.clientX){
		// In Internet Explorer 7 some properties (mouse coordinates) are treated as physical,
		// while others are logical (offset).
		var zoom = 1;
		var body = document.body;

		if (body.getBoundingClientRect) {
			var bound = body.getBoundingClientRect();
			zoom = (bound.right - bound.left)/body.clientWidth;
		}

		return {
			x: e.clientX / zoom + document.body.scrollLeft + document.documentElement.scrollLeft,
			y: e.clientY / zoom + document.body.scrollTop + document.documentElement.scrollTop
		};
	}

	return {
		x: e.pageX,
		y: e.pageY
	};

}
/**
 * Function generates unique id
 */
var ajax_upload_getUID = function(){
	var id = 0;
	return function(){
		return 'ValumsAjaxUpload' + id++;
	}
}();

function ajax_upload_fileFromPath(file){
	return file.replace(/.*(\/|\\)/, "");
}

function ajax_upload_getExt(file){
	return (/[.]/.exec(file)) ? /[^.]+$/.exec(file.toLowerCase()) : '';
}

// Please use AjaxUpload , Ajax_upload will be removed in the next version
Ajax_upload = AjaxUpload = function(button, options){
	if (button.jquery){
		// jquery object was passed
		button = button[0];
	} else if (typeof button == "string" && /^#.*/.test(button)){
		button = button.slice(1);
	}
	button = ajax_upload_get(button);

	this._input = null;
	this._button = button;
	this._disabled = false;
	this._submitting = false;
	// Variable changes to true if the button was clicked
	// 3 seconds ago (requred to fix Safari on Mac error)
	this._justClicked = false;
	this._parentDialog = document.body;

	if (window.jQuery && jQuery.ui && jQuery.ui.dialog){
		var parentDialog = jQuery(this._button).parents('.ui-dialog');
		if (parentDialog.length){
			this._parentDialog = parentDialog[0];
		}
	}

	this._settings = {
		// Location of the server-side upload script
		action: 'upload.php',
		// File upload name
		name: 'userfile',
		// Additional data to send
		data: {},
		// Submit file as soon as it's selected
		autoSubmit: true,
		// The type of data that you're expecting back from the server.
		// Html and xml are detected automatically.
		// Only useful when you are using json data as a response.
		// Set to "json" in that case.
		responseType: false,
		// When user selects a file, useful with autoSubmit disabled
		onChange: function(file, extension){},
		// Callback to fire before file is uploaded
		// You can return false to cancel upload
		onSubmit: function(file, extension){},
		// Fired when file upload is completed
		// WARNING! DO NOT USE "FALSE" STRING AS A RESPONSE!
		onComplete: function(file, response) {}
	};

	// Merge the users options with our defaults
	for (var i in options) {
		this._settings[i] = options[i];
	}

	this._createInput();
	this._rerouteClicks();
}

// assigning methods to our class
AjaxUpload.prototype = {
	setData : function(data){
		this._settings.data = data;
	},
	disable : function(){
		this._disabled = true;
	},
	enable : function(){
		this._disabled = false;
	},
	// removes ajaxupload
	destroy : function(){
		if(this._input){
			if(this._input.parentNode){
				this._input.parentNode.removeChild(this._input);
			}
			this._input = null;
		}
	},
	/**
	 * Creates invisible file input above the button
	 */
	_createInput : function(){
		var self = this;
		var input = document.createElement("input");
		input.setAttribute('type', 'file');
		input.setAttribute('name', this._settings.name);
		var styles = {
			'position' : 'absolute'
			,'margin': '-5px 0 0 -175px'
			,'padding': 0
			,'width': '220px'
			,'height': '30px'
			,'fontSize': '14px'
			,'opacity': 0
			,'cursor': 'pointer'
			,'display' : 'none'
			,'zIndex' :  2147483583 //Max zIndex supported by Opera 9.0-9.2x
			// Strange, I expected 2147483647
		};
		for (var i in styles){
			input.style[i] = styles[i];
		}

		// Make sure that element opacity exists
		// (IE uses filter instead)
		if ( ! (input.style.opacity === "0")){
			input.style.filter = "alpha(opacity=0)";
		}

		this._parentDialog.appendChild(input);

		ajax_upload_addEvent(input, 'change', function(){
			// get filename from input
			var file = ajax_upload_fileFromPath(this.value);
			if(self._settings.onChange.call(self, file, ajax_upload_getExt(file)) == false ){
				return;
			}
			// Submit form when value is changed
			if (self._settings.autoSubmit){
				self.submit();
			}
		});

		// Fixing problem with Safari
		// The problem is that if you leave input before the file select dialog opens
		// it does not upload the file.
		// As dialog opens slowly (it is a sheet dialog which takes some time to open)
		// there is some time while you can leave the button.
		// So we should not change display to none immediately
		ajax_upload_addEvent(input, 'click', function(){
			self.justClicked = true;
			setTimeout(function(){
				// we will wait 3 seconds for dialog to open
				self.justClicked = false;
			}, 3000);
		});

		this._input = input;
	},
	_rerouteClicks : function (){
		var self = this;

		// IE displays 'access denied' error when using this method
		// other browsers just ignore click()
		// addEvent(this._button, 'click', function(e){
		//   self._input.click();
		// });

		var box, dialogOffset = {top:0, left:0}, over = false;
		ajax_upload_addEvent(self._button, 'mouseover', function(e){
			if (!self._input || over) return;
			over = true;
			box = ajax_upload_getBox(self._button);

			if (self._parentDialog != document.body){
				dialogOffset = ajax_upload_getOffset(self._parentDialog);
			}
		});


		// we can't use mouseout on the button,
		// because invisible input is over it
		ajax_upload_addEvent(document, 'mousemove', function(e){
			var input = self._input;
			if (!input || !over) return;

			if (self._disabled){
				ajax_upload_removeClass(self._button, 'hover');
				input.style.display = 'none';
				return;
			}

			var c = ajax_upload_getMouseCoords(e);

			if ((c.x >= box.left) && (c.x <= box.right) &&
			(c.y >= box.top) && (c.y <= box.bottom)){
				input.style.top = c.y - dialogOffset.top + 'px';
				input.style.left = c.x - dialogOffset.left + 'px';
				input.style.display = 'block';
				ajax_upload_addClass(self._button, 'hover');
			} else {
				// mouse left the button
				over = false;
				if (!self.justClicked){
					input.style.display = 'none';
				}
				ajax_upload_removeClass(self._button, 'hover');
			}
		});

	},
	/**
	 * Creates iframe with unique name
	 */
	_createIframe : function(){
		// unique name
		// We cannot use getTime, because it sometimes return
		// same value in safari :(
		var id = ajax_upload_getUID();

		// Remove ie6 "This page contains both secure and nonsecure items" prompt
		// http://tinyurl.com/77w9wh
		var iframe = ajax_upload_toElement('<iframe src="javascript:false;" name="' + id + '" />');
		iframe.id = id;
		iframe.style.display = 'none';
		document.body.appendChild(iframe);
		return iframe;
	},
	/**
	 * Upload file without refreshing the page
	 */
	submit : function(){
		var self = this, settings = this._settings;

		if (this._input.value === ''){
			// there is no file
			return;
		}

		// get filename from input
		var file = ajax_upload_fileFromPath(this._input.value);

		// execute user event
		if (! (settings.onSubmit.call(this, file, ajax_upload_getExt(file)) == false)) {
			// Create new iframe for this submission
			var iframe = this._createIframe();

			// Do not submit if user function returns false
			var form = this._createForm(iframe);
			form.appendChild(this._input);

			form.submit();

			document.body.removeChild(form);
			form = null;
			this._input = null;

			// create new input
			this._createInput();

			var toDeleteFlag = false;

			ajax_upload_addEvent(iframe, 'load', function(e){

				if (// For Safari
					iframe.src == "javascript:'%3Chtml%3E%3C/html%3E';" ||
					// For FF, IE
					iframe.src == "javascript:'<html></html>';"){

					// First time around, do not delete.
					if( toDeleteFlag ){
						// Fix busy state in FF3
						setTimeout( function() {
							document.body.removeChild(iframe);
						}, 0);
					}
					return;
				}

				var doc = iframe.contentDocument ? iframe.contentDocument : frames[iframe.id].document;

				// fixing Opera 9.26
				if (doc.readyState && doc.readyState != 'complete'){
					// Opera fires load event multiple times
					// Even when the DOM is not ready yet
					// this fix should not affect other browsers
					return;
				}

				// fixing Opera 9.64
				if (doc.body && doc.body.innerHTML == "false"){
					// In Opera 9.64 event was fired second time
					// when body.innerHTML changed from false
					// to server response approx. after 1 sec
					return;
				}

				var response;

				if (doc.XMLDocument){
					// response is a xml document IE property
					response = doc.XMLDocument;
				} else if (doc.body){
					// response is html document or plain text
					response = doc.body.innerHTML;
					if (settings.responseType && settings.responseType.toLowerCase() == 'json'){
						// If the document was sent as 'application/javascript' or
						// 'text/javascript', then the browser wraps the text in a <pre>;
						// tag and performs html encoding on the contents.  In this case,
						// we need to pull the original text content from the text node's
						// nodeValue property to retrieve the unmangled content.
						// Note that IE6 only understands text/html
						if (doc.body.firstChild && doc.body.firstChild.nodeName.toUpperCase() == 'PRE'){
							response = doc.body.firstChild.firstChild.nodeValue;
						}
						if (response) {
							response = window["eval"]("(" + response + ")");
						} else {
							response = {};
						}
					}
				} else {
					// response is a xml document
					var response = doc;
				}

				settings.onComplete.call(self, file, response);

				// Reload blank page, so that reloading main page
				// does not re-submit the post. Also, remember to
				// delete the frame
				toDeleteFlag = true;

				// Fix IE mixed content issue
				iframe.src = "javascript:'<html></html>';";
			});

		} else {
			// clear input to allow user to select same file
			// Doesn't work in IE6
			// this._input.value = '';
			document.body.removeChild(this._input);
			this._input = null;

			// create new input
			this._createInput();
		}
	},
	/**
	 * Creates form, that will be submitted to iframe
	 */
	_createForm : function(iframe){
		var settings = this._settings;
		// method, enctype must be specified here
		// because changing this attr on the fly is not allowed in IE 6/7
		var form = ajax_upload_toElement('<form method="post" enctype="multipart/form-data" action=""><input type="hidden" name="id_product" value="' + $('input[type=hidden][name=id_product]').val() + '"/></form>');
		form.style.display = 'none';
		form.action = settings.action;
		form.target = iframe.name;
		document.body.appendChild(form);

		// Create hidden input element for each data key
		for (var prop in settings.data){
			var el = document.createElement("input");
			el.type = 'hidden';
			el.name = prop;
			el.value = settings.data[prop];
			form.appendChild(el);
		}
		return form;
	}
};
// ******************************************** FINE AJAXUPLOAD ************************************************* //

// ************************************************* SLIDER ***************************************************** //
/*
 * USO:
 *
 *      var my_slider = $(contenitore).get_slider({
 *          opzione1 : valore1,
 *          opzione2 : valore2,
 *                  ...
 *      });
 *
 * OPZIONI:
 *
 *      width :                Larghezza del contenitore delle news
 *      height :               Altezza del contenitore delle news
 *      scroll_type :          Se settato a "jcarousel" utilizza jcarousel altrimenti scorre in automatico
 *      where :                Se settato a "from_today" visualizza solo le news con data di pubblicazione maggiore o uguale ad oggi altrimenti tutte
 *      type :                 "orizontal" o "vertical"
 *      date_format:           | %d => "14" | %dd => "Lun" | %ddd => "Lunedì" | %m => "11" | %mm => "Nov" | %mmm => "Novembre" | %yy => "'11" | %yyyy => "2011" |
 *      image:                 Se settato ( 1 ) inserisce anche l'immagine
 *
 *      ajax * :               Se settato carica le news tramite ajax solo quando necessario
 *      items_number * :       Numero di news visibili nel carousel
 *      scroll * :             Numero di posizioni di cui trasla alla pressione dei bottoni di scroll
 *
 *      interval **:           Millisecondi di attesa per lo scorrimento automatico (insieme ai due parametri sotto consente di modificare la velocità di scorrimento)
 *      pixel_step_x ** :      Grandezza in pixel dello scorrimento orizzontale (consentiti anche numeri minori di 1 come 0.01)
 *      pixel_step_y ** :      Grandezza in pixel dello scorrimento verticale (consentiti anche numeri minori di 1 come 0.01)
 *      continuous ** :        Se settato ( 1 ) crea uno scorrimento automatico continuo
 *      direction ** :         "up" "right" "down" "left"
 *      stop_flag ** :         Se settato ( 1 ) al caricamento della pagina le news non scorrono
 *
 *      *  : opzioni valide solo se scroll_type = "jcarousel"
 *      ** : opzioni valide solo se scroll_type non e' settato
 *
 * METODI:
 *      Utilizzabili solo con lo scorrimento automatico (scroll_type non settato)
 *      my_slider.set_direction('left');
 *      my_slider.start();
 *      my_slider.stop();
 *
 */



$.slider = function(configuration){
    var s = this;
    var _container = configuration.container;
    var _width = configuration.width || _container.parent().width();
    var _height = configuration.height || _container.parent().height();
    var _ajax = configuration.ajax ? true : false;
    var _list,_timeout,_configure,_slide,_init,k,jdata,_offset,news_number;
    var where = configuration.where == 'from_today' ? 'from_today' : '*';
    var _image = configuration.image ? 1 : 0;
    // ****************************** CAROUSEL ****************************** //
    if(configuration.scroll_type == 'jcarousel'){
        $.ajax({
            async: false,
            method: 'post',
            url: '/news-getCount/?w=' + where,
            success: function(data) {
                jdata = $.parseJSON(data);
            }
        });
        _offset = jdata.resp[0] !== undefined ? parseInt(jdata.resp[0].c) : 0;
        news_number = _offset + parseInt(jdata.resp[1].c);
        _init = function(){
            var html,_item_width,_item_height,_limit,_load;
            var type = configuration.type == 'orizontal' ? 'orizontal' : 'vertical';
            var items_number = configuration.items_number || 1;
            var scroll = configuration.scroll || 1;
            var c = 0;
            var id = 'first-carousel';

            if(type == 'orizontal'){
                _item_width = Math.round(_width/items_number);
                _width = _item_width*items_number;
                _item_height = _height;
            } else {
                _item_height = Math.round(_height/items_number);
                _height = _item_height*items_number;
                _item_width = _width;
            }
            s.date_format = configuration.date_format || '%d-%m-%yyyy';
            if(news_number - _offset < items_number){
                _offset = news_number - items_number;
            }
            // ****************************** AJAX ****************************** //
            if(_ajax){
                $.ajax({
                    async: false,
                    method: 'post',
                    url: '/news-get/?w=' + where + '&l=' + items_number + '&o=' + _offset,
                    success: function(data) {
                        jdata = $.parseJSON(data);
                    }
                });
                if($('#' + id).length){
                    id = 'second-carousel';
                }
                html = '<ul id="' + id + '" class="jcarousel-skin-news">';

                for(k = 0; k < _offset; k++){
                    html += '<li class="to_load" style="position:relative;width:' + _item_width + 'px;height:' + _item_height + 'px;max-height:' + _item_height + 'px;">';
                    html += '<img src="/images/loader3.gif" ' + (type == 'vertical' ? ' style="width:50%;margin-left:25%;" ' : ' style="height:50%;margin-top:25%;" ') + ' alt=""/></li>';
                    c++;
                }

                for(k in jdata.resp){
                    html += '<li style="position:relative;"><div ' + (type == 'vertical' ? ' style="min-height:90%;max-height:90%;padding-top:10%;" ' : ' style="width:90%" ') + '>';
                    html += (_image ? '<div class="news_image"><img src="'+ (jdata.resp[k].picture ? jdata.resp[k].picture : '/images/news.jpg') + '" alt=""/></div>' : '');
                    html += '<div class="news_date" ' + (type == 'vertical' ? ' style="width:' + _width + 'px;" ' : '') + '>' +
                                (jdata.resp[k].show_date === '1' ?
                                    (typeof jdata.resp[k].complete_date === 'string' ?
                                        jdata.resp[k].complete_date :
                                        s.date_format.replace( /%(.)\1*/g,function(s){return jdata.resp[k].complete_date[s];})) :
                                    '') +
                            '</div>';
                    html += '<div class="news_subject" ' + (type == 'vertical' ? ' style="width:' + _width + 'px;" ' : '') + '>' +
                                (jdata.resp[k].dest_url ?
                                    '<a href="' + jdata.resp[k].dest_url + '" target="' + jdata.resp[k].dest_target + '">' + jdata.resp[k].subject + '</a></div>':
                                    jdata.resp[k].subject + '</div>');
                    html += '<div class="news_body" ' + (type == 'vertical' ? ' style="width:' + _width + 'px;" ' : '') + '>' + jdata.resp[k].body + '</div>';
                    html += '<div class="news_bottom" style="position:relative;min-height:' + _item_height + 'px;min-width:' + _item_width + 'px;">&nbsp;';
                    html += '<span style="display:none;">[ ... ]</span><a style="display:none;" href="/news-detail/?id_news=' + jdata.resp[k].id_news + '">Continua</a></div></div></li>';
                    c++;
                }
                for(k = c; k < news_number; k++){
                    html += '<li class="to_load" style="position:relative;width:' + _item_width + 'px;height:' + _item_height + 'px;max-height:' + _item_height + 'px;">';
                    html += '<img src="/images/loader3.gif" ' + (type == 'vertical' ? ' style="width:50%;margin-left:25%;" ' : ' style="height:50%;margin-top:25%;" ') + ' alt=""/></li>';
                }

                html += '</ul>';
                _container.append(html);
                if(type == 'orizontal'){
                    _item_width = Math.round(_width/items_number);
                    _width = _item_width*items_number;
                    $('#' + id).jcarousel({
                        orizontal : true,
                        start : _offset+1,
                        item_width : _item_width,
                        item_height : _item_height,
                        scroll : scroll,
                        itemLoadCallback : function(carousel,op){
                            _load = 0;
                            if(op === 'next' && $('#' + id + ' li:nth-child(' + carousel.last + ')').hasClass('to_load')){
                                _limit = carousel.last - carousel.prevLast;
                                _offset = carousel.prevLast;
                                _load = 1;
                            } else if(op === 'prev' && $('#' + id + ' li:nth-child(' + carousel.first + ')').hasClass('to_load')){
                                _limit = carousel.prevFirst - carousel.first;
                                _offset = carousel.first - 1;
                                _load = 1;
                            } else if(op === 'init') {
                                carousel.last = carousel.first + items_number - 1;
                            }
                            if(_load){
                                $.ajax({
                                    method: 'post',
                                    url: '/news-get/?w=' + where + '&l=' + _limit + '&o=' + _offset,
                                    success: function(data) {
                                        var i = 1,
                                            html;
                                        jdata = $.parseJSON(data);
                                        for(k in jdata.resp){
                                            html = '<div style="width:90%">';
                                            html += (_image ? '<div class="news_image"><img src="'+ (jdata.resp[k].picture ? jdata.resp[k].picture : '/images/news.jpg') + '" alt=""/></div>' : '');
                                            html += '<div class="news_date">' +
                                                        (jdata.resp[k].show_date === '1' ?
                                                            (typeof jdata.resp[k].complete_date === 'string' ?
                                                                jdata.resp[k].complete_date :
                                                                s.date_format.replace( /%(.)\1*/g,function(s){return jdata.resp[k].complete_date[s];})) :
                                                            '') +
                                                    '</div>';
                                            html += '<div class="news_subject">' +
                                                    (jdata.resp[k].dest_url ?
                                                        '<a href="' + jdata.resp[k].dest_url + '" target="' + jdata.resp[k].dest_target + '">' + jdata.resp[k].subject + '</a></div>':
                                                        jdata.resp[k].subject + '</div>');
                                            html += '<div class="news_body">' + jdata.resp[k].body + '</div>';
                                            html += '<div class="news_bottom" style="position:relative;min-height:' + _item_height + 'px;min-width:' + _item_width + 'px;">&nbsp;';
                                            html += '<span style="display:none;">[ ... ]</span><a style="display:none;" href="/news-detail/?id_news=' + jdata.resp[k].id_news + '">Continua</a></div></div></li>';
                                            $('#' + id + ' li:nth-child(' + parseInt(_offset + i) + ')').removeClass('to_load').html(html).children(0).text_cut();
                                            i++;
                                        }
                                    }
                                });
                            }
                        },
                        initCallback: function(){
                            $('.jcarousel-skin-news .jcarousel-container-horizontal:has(#' + id + ')').css({'width':_width+'px'});
                            $('.jcarousel-skin-news .jcarousel-clip-horizontal:has(#' + id + ')').css({'width':_width+'px','height':_height+'px'});
                            $('.jcarousel-skin-news #' + id + ' .jcarousel-item-horizontal').css({'width':_item_width+'px','height':_height+'px'});
                        }
                    });

                } else {
                    _item_height = Math.round(_height/items_number);
                    _height = _item_height*items_number;
                    $('#' + id).jcarousel({
                        vertical : true,
                        start : _offset+1,
                        item_width : _item_width,
                        item_height : _item_height,
                        scroll : scroll,
                        initCallback: function(){
                            $('.jcarousel-skin-news .jcarousel-container-vertical:has(#' + id + ')').css({'width':_width+'px'});
                            $('.jcarousel-skin-news .jcarousel-clip-vertical:has(#' + id + ')').css({'width':_width+'px','max-height':_height+'px','height':_height+'px'});
                            $('.jcarousel-skin-news #' + id + ' .jcarousel-item-vertical').css({'width':_width+'px','max-height':_item_height+'px','height':_item_height+'px'});
                        },
                        itemLoadCallback : function(carousel,op){
                            _load = 0;
                            if(op === 'next' && $('#' + id + ' li:nth-child(' + carousel.last + ')').hasClass('to_load')){
                                _limit = carousel.last - carousel.prevLast;
                                _offset = carousel.prevLast;
                                _load = 1;
                            } else if(op === 'prev' && $('#' + id + ' li:nth-child(' + carousel.first + ')').hasClass('to_load')){
                                _limit = carousel.prevFirst - carousel.first;
                                _offset = carousel.first - 1;
                                _load = 1;
                            } else if(op === 'init') {
                                carousel.last = carousel.first + items_number - 1;
                            }
                            if(_load){
                                $.ajax({
                                    method: 'post',
                                    url: '/news-get/?w=' + where + '&l=' + _limit + '&o=' + _offset,
                                    success: function(data) {
                                        var i = 1,
                                            html;
                                        jdata = $.parseJSON(data);
                                        for(k in jdata.resp){
                                            html = '<div style="min-height:90%;max-height:90%;padding-top:10%;">';
                                            html += (_image ? '<div class="news_image"><img src="'+ (jdata.resp[k].picture ? jdata.resp[k].picture : '/images/news.jpg') + '" alt=""/></div>' : '');
                                            html += '<div class="news_date" style="width:' + _width + 'px;" >' +
                                                        (jdata.resp[k].show_date === '1' ?
                                                            (typeof jdata.resp[k].complete_date === 'string' ?
                                                                jdata.resp[k].complete_date :
                                                                s.date_format.replace( /%(.)\1*/g,function(s){return jdata.resp[k].complete_date[s];})) :
                                                            '') +
                                                    '</div>';
                                            html += '<div class="news_subject" style="width:' + _width + 'px;">' +
                                                    (jdata.resp[k].dest_url ?
                                                        '<a href="' + jdata.resp[k].dest_url + '" target="' + jdata.resp[k].dest_target + '">' + jdata.resp[k].subject + '</a></div>':
                                                        jdata.resp[k].subject + '</div>');
                                            html += '<div class="news_body" style="width:' + _width + 'px;" >' + jdata.resp[k].body + '</div>';
                                            html += '<div class="news_bottom" style="position:relative;min-height:' + _item_height + 'px;min-width:' + _item_width + 'px;">&nbsp;';
                                            html += '<span style="display:none;">[ ... ]</span><a style="display:none;" href="/news-detail/?id_news=' + jdata.resp[k].id_news + '">Continua</a></div></div>';
                                            $('#' + id + ' li:nth-child(' + parseInt(_offset + i) + ')').removeClass('to_load').html(html).children(0).text_cut();
                                            i++;
                                        }
                                    }
                                });
                            }
                        }
                    });
                }
                if(items_number >= news_number){
                    $('.jcarousel-skin-news #' + id).parent().nextAll('.jcarousel-prev-horizontal').removeClass('jcarousel-prev-horizontal');
                    $('.jcarousel-skin-news #' + id).parent().nextAll('.jcarousel-prev-vertical').removeClass('jcarousel-prev-vertical');
                    $('.jcarousel-skin-news #' + id).parent().nextAll('.jcarousel-next-horizontal').removeClass('jcarousel-next-horizontal');
                    $('.jcarousel-skin-news #' + id).parent().nextAll('.jcarousel-next-vertical').removeClass('jcarousel-next-vertical');
                }
                $('.jcarousel-item > div').text_cut();
            // ****************************** NON AJAX ****************************** //
            } else {
                $.ajax({
                    async: false,
                    method: 'post',
                    url: '/news-get/?w=' + where,
                    success: function(data) {
                        jdata = $.parseJSON(data);
                    }
                });
                if($('#' + id).length){
                    id = 'second-carousel';
                }
                html = '<ul id="' + id + '" class="jcarousel-skin-news">';

                for(k in jdata.resp){
                    html += '<li style="position:relative;"><div ' + (type == 'vertical' ? ' style="min-height:90%;max-height:90%;padding-top:10%;" ' : ' style="width:90%" ') + '>';
                    html += (_image ? '<div class="news_image"><img src="'+ (jdata.resp[k].picture ? jdata.resp[k].picture : '/images/news.jpg') + '" alt=""/></div>' : '');
                    html += '<div class="news_date" ' + (type == 'vertical' ? ' style="width:' + _width + 'px;" ' : '') + '>' +
                                (jdata.resp[k].show_date === '1' ?
                                    (typeof jdata.resp[k].complete_date === 'string' ?
                                        jdata.resp[k].complete_date :
                                        s.date_format.replace( /%(.)\1*/g,function(s){return jdata.resp[k].complete_date[s];})) :
                                    '') +
                            '</div>';
                    html += '<div class="news_subject" ' + (type == 'vertical' ? ' style="width:' + _width + 'px;" ' : '') + '>' +
                            (jdata.resp[k].dest_url ?
                                '<a href="' + jdata.resp[k].dest_url + '" target="' + jdata.resp[k].dest_target + '">' + jdata.resp[k].subject + '</a></div>':
                                jdata.resp[k].subject + '</div>');
                    html += '<div class="news_body" ' + (type == 'vertical' ? ' style="width:' + _width + 'px;" ' : '') + '>' + jdata.resp[k].body + '</div>';
                    html += '<div class="news_bottom" style="position:relative;min-height:' + _item_height + 'px;min-width:' + _item_width + 'px;">&nbsp;';
                    html += '<span style="display:none;">[ ... ]</span><a style="display:none;" href="/news-detail/?id_news=' + jdata.resp[k].id_news + '">Continua</a></div></div></li>';
                }
                html += '</ul>';
                _container.append(html);
                if(type == 'orizontal'){
                    $('#' + id).jcarousel({
                        orizontal : true,
                        start : _offset+1,
                        item_width : _item_width,
                        item_height : _item_height,
                        scroll : scroll,
                        initCallback: function(){
                            $('.jcarousel-skin-news .jcarousel-container-horizontal:has(#' + id + ')').css({'width':_width+'px'});
                            $('.jcarousel-skin-news .jcarousel-clip-horizontal:has(#' + id + ')').css({'width':_width+'px','height':_height+'px'});
                            $('.jcarousel-skin-news #' + id + ' .jcarousel-item-horizontal').css({'width':_item_width+'px','height':_height+'px'});
                        }
                    });
                } else {
                    $('#' + id).jcarousel({
                        vertical : true,
                        start : _offset+1,
                        item_width : _item_width,
                        item_height : _item_height,
                        scroll : scroll,
                        initCallback: function(){
                            $('.jcarousel-skin-news .jcarousel-container-vertical:has(#' + id + ')').css({'width':_width+'px'});
                            $('.jcarousel-skin-news .jcarousel-clip-vertical:has(#' + id + ')').css({'width':_width+'px','max-height':_height+'px','height':_height+'px'});
                            $('.jcarousel-skin-news #' + id + ' .jcarousel-item-vertical').css({'width':_width+'px','max-height':_item_height+'px','height':_item_height+'px'});
                        }
                    });
                }
                if(items_number >= news_number){
                    $('.jcarousel-skin-news #' + id).parent().nextAll('.jcarousel-prev-horizontal').removeClass('jcarousel-prev-horizontal');
                    $('.jcarousel-skin-news #' + id).parent().nextAll('.jcarousel-prev-vertical').removeClass('jcarousel-prev-vertical');
                    $('.jcarousel-skin-news #' + id).parent().nextAll('.jcarousel-next-horizontal').removeClass('jcarousel-next-horizontal');
                    $('.jcarousel-skin-news #' + id).parent().nextAll('.jcarousel-next-vertical').removeClass('jcarousel-next-vertical');
                }
                $('.jcarousel-item > div').text_cut();
            }
        }
    // ****************************** SCORRIMENTO ****************************** //
    } else {
        _init = function(){
            var jdata,html,html_tmp = '';
            var type = configuration.type == 'orizontal' ? 'orizontal' : 'vertical';
            var where = configuration.where == 'from_today' ? 'from_today' : '*';
            s.date_format = configuration.date_format || '%d-%m-%yyyy';
            s.continuous = configuration.continuous || 0;
            $.ajax({
                async: false,
                method: 'post',
                url: '/news-get/?ordered=1&w=' + where,
                success: function(data) {
                    jdata = $.parseJSON(data);
                }
            });
            _width = _width > 30 ? _width - 30 : 100;
            _height = _height > 30 ? _height - 30 : 100;
            if(type == 'orizontal'){
                html = '<table style="display:inline;"><tr>';
                html_tmp = '';
                for(k in jdata.resp){
                    html_tmp += '<td nowrap="nowrap">';
                    html_tmp += (_image ? '<div class="news_image"><img src="'+ (jdata.resp[k].picture ? jdata.resp[k].picture : '/images/news.jpg') + '" alt=""/></div>' : '');
                    html_tmp += '<div class="news_date" style="display:inline;padding-right:10px;">' +
                                    (jdata.resp[k].show_date === '1' ?
                                        (typeof jdata.resp[k].complete_date === 'string' ?
                                            jdata.resp[k].complete_date :
                                            s.date_format.replace( /%(.)\1*/g,function(s){return jdata.resp[k].complete_date[s];})) :
                                        '') +
                                '</div>';
                    html_tmp += '<div class="news_subject" style="display:inline;padding-right:10px;">' +
                            (jdata.resp[k].dest_url ?
                                '<a href="' + jdata.resp[k].dest_url + '" target="' + jdata.resp[k].dest_target + '">' + jdata.resp[k].subject + '</a></div>':
                                jdata.resp[k].subject + '</div>');
                    html_tmp += '<div class="news_body" style="display:inline;padding-right:20px;">' + jdata.resp[k].body + '</div>';
                    html_tmp += '</td>';
                }
                html += html_tmp;
                if(s.continuous){
                    html += html_tmp;
                }
                html += '</tr></table>';
            } else {
                html = '<ul style="list-style-type: none;margin: 0px;padding:5px;">';
                html_tmp = '';
                for(k in jdata.resp){
                    html_tmp += '<li>';
                    html_tmp += (_image ? '<div class="news_image"><img src="'+ (jdata.resp[k].picture ? jdata.resp[k].picture : '/images/news.jpg') + '" alt=""/></div>' : '');
                    html_tmp += '<div class="news_date">' +
                                    (jdata.resp[k].show_date === '1' ?
                                        (typeof jdata.resp[k].complete_date === 'string' ?
                                            jdata.resp[k].complete_date :
                                            s.date_format.replace( /%(.)\1*/g,function(s){return jdata.resp[k].complete_date[s];})) :
                                        '') +
                                '</div>';
                    html_tmp += '<div class="news_subject">' +
                            (jdata.resp[k].dest_url ?
                                '<a href="' + jdata.resp[k].dest_url + '" target="' + jdata.resp[k].dest_target + '">' + jdata.resp[k].subject + '</a></div>':
                                jdata.resp[k].subject + '</div>');
                    html_tmp += '<div class="news_body">' + jdata.resp[k].body + '</div>';
                    html_tmp += '</li>';
                }
                html += html_tmp;
                if(s.continuous){
                    html += html_tmp;
                }
                html += '</ul>';
            }

            _container
                .css({'overflow':'hidden','position':'relative','padding':'0px','width': _width+'px','height': _height+'px'})
                .wrap('<div class="news-container" style="width:'+_width+'px;height:'+_height+'px;padding:15px;"/>');

            _container.append(html);

            _list = _container.children();
            _list.css({'position':'absolute'});
            _list.children().each(function(){
                $(this).css({'width':$(this).width() + 'px','height':$(this).height() + 'px'});
            });
            s.list_height = Math.round(_list.height());
            s.list_width = Math.round(_list.width());
            s.container_height = Math.round(_container.height());
            s.container_width = Math.round(_container.width());
            s.direction = configuration.direction;
            s.top = 0;
            s.left = 0;
            _list.css({top : s.top + 'px', left : s.left} );
            s.x = configuration.pixel_step_x || 1;
            s.y = configuration.pixel_step_y || 1;
            s.interval = configuration.interval || 10;
            s.stop_flag = configuration.stop_flag === 1 ? 1 : 0;
            if($.browser.msie && (parseInt($.browser.version, 10) < 9)){
                s.x = s.x / 100;
                s.y = s.y / 100;
            }
            s.slide = function(){
                clearTimeout(_timeout);
                if(!s.stop_flag){
                    _slide();
                    _timeout = setTimeout(s.slide,s.interval);
                }
            }

            s.stop = function(){
                s.stop_flag = 1;
                s.slide();
            }

            s.start = function(){
                s.stop_flag = 0;
                s.slide();
            }

            s.set_direction = function(direction){
                s.direction = direction;
                _configure();
            }
        };

        _configure = function(){
            switch(s.direction){
                case 'right':
                    _slide = function(){
                        clearTimeout(_timeout);
                        s.left = s.left + s.x;
                        _list.css('left',s.left + 'px');
                        if(s.continuous){
                            if(s.left > (s.list_width/2*(-1) + s.container_width)){
                                s.left = (s.left - s.list_width/2);
                            }
                        } else {
                            if(s.left > s.container_width){
                                s.left = s.list_width*(-1);
                            }
                        }
                        _timeout = setTimeout(s.slide,s.interval);
                    }
                    break;
                case 'down':
                    _slide = function(){
                        clearTimeout(_timeout);
                        s.top = s.top + s.y;
                        _list.css('top',s.top + 'px');
                        if(s.continuous){
                            if(s.top > (s.list_height/2*(-1) + s.container_height)){
                                s.top = (s.top - s.list_height/2);
                            }
                        } else {
                            if(s.top > s.container_height){
                                s.top = s.list_height*(-1);
                            }
                        }
                        _timeout = setTimeout(s.slide,s.interval);
                    }

                    break;
                case 'left':
                    _slide = function(){
                        clearTimeout(_timeout);
                        s.left = s.left - s.x;
                        _list.css('left',s.left + 'px');
                        if(s.continuous){
                            if(s.left < s.list_width*(-1)/2){
                                s.left = (s.left + s.list_width/2);
                            }
                        } else {
                           if(s.left < s.list_width*(-1)){
                               s.left = s.container_width;
                           }
                        }

                        _timeout = setTimeout(s.slide,s.interval);
                    }

                    break;
                default:
                    s.direction = 'up';
                    _slide = function(){
                        clearTimeout(_timeout);
                        s.top = s.top - s.y;
                        _list.css('top',s.top + 'px');
                        if(s.continuous){
                            if(s.top < s.list_height*(-1)/2){
                                s.top = (s.top + s.list_height/2);
                            }
                        } else {
                           if(s.top < s.list_height*(-1)){
                               s.top = s.container_height;
                           }
                        }
                        _timeout = setTimeout(s.slide,s.interval);
                    }

            }
        }
        _configure();
    }
    _init();
}

// *********************************************** FINE SLIDER ************************************************** //


// *********************************************** TEXTCUT ***************************************************** //
$.fn.text_cut = function(){
    return new $.text_cut($(this));
}

$.text_cut = function(selector){
    selector.children().each(function(){
        if($(this).position().top + $(this).height() > selector.parent().height() && this.className !== 'news_bottom'){
            var h = $(this).parent().parent().height() - $(this).position().top;
            var lh = Math.round(parseInt($(this).css('font-size'))+2);
            var ln = Math.floor(h/lh);
            var bottom = $(this).nextAll('.news_bottom');
            var ie_add = $.browser.msie ? 1 : 0;
            $(this).css('line-height',h/ln + 'px');
            bottom.css({'position' : 'absolute','line-height':h/ln + 'px','min-height':(h/ln*2+ie_add) + 'px' ,'max-height':(h/ln*2+ie_add) + 'px' ,'bottom':0, 'z-index':1000, 'background-color':'#F0F6F9'});
            bottom.children('span').css({'display':'inline','text-align':'left','position':'absolute','left':'0px'});
            bottom.children('a').css({'display':'block','text-align':'right','padding-right':'15%'});
        }
    });
}
