var wptn =
{
    pluginURL	    : null
};

/*
   Constructeur de l'objet wptn.navigation
*/
wptn.navigation = function(container, pageIndex, nbPages, nbThumbnails, selectedPostId)
{
    this.container		= jQuery(container); 
    this.pageIndex		= 0; // l'index de la page (>=1)
    this.nbPages		= nbPages;
    this.nbThumbnails		= nbThumbnails;
    this.loadedPages		= [];
    this.selectedPostId		= selectedPostId;

    /*
       Initialisation 
    */

    var thumbnails = this.container.find("div.thumbnails").css({overflow : "hidden", position : "relative"});

    // on déduit le css d'une page
    this.pageCss = { width : thumbnails.width(), height : thumbnails.height(), "float" : "left" };

    // on récupère le page container
    this.pagesContainer = jQuery("div.pages", thumbnails).css({width : thumbnails.width(), height : thumbnails.height(), position : "absolute"});

    // on prepare le div de preview
    this.preview = jQuery(document.createElement("div")).addClass("preview").hide().css({position:"absolute", opacity:0}).prependTo(this.container);

    /*
       On récupère les premières pages loadées
    */

    var _this = this;
    var firstPage = null;

    this.pagesContainer.find("div.page").each
    (
	function()
	{
	    firstPage = firstPage || _this._createPageFromDom(this);
	}
    );

    /*
       On rajoute le before et le after
    */

    this.before	= jQuery(document.createElement("div")).addClass("empty").css(this.pageCss).prependTo(this.pagesContainer);
    this.after	= jQuery(document.createElement("div")).addClass("empty").css(this.pageCss).appendTo(this.pagesContainer);

    /*
       Si des pages ont été prédéfinies ont se repositionne
    */

    if ( firstPage )
    {
        this._updateWidthAndPos(firstPage);
    }

    /*
       Initialisation du comportemant 
       des boutons de scroll
    */

    this.container.find("div.scroll.next a").click
    (
	function()
	{
	    _this.next();
	}
    );

    this.container.find("div.scroll.prev a").click
    (
	function()
	{
	    _this.prev();
	}
    );

    this.container.find("div.footer a.first").click
    (
	function()
	{
	    _this.first();
	}
    );

    this.container.find("div.footer a.last").click
    (
	function()
	{
	    _this.last();
	}
    );

    this.container.find("div.footer a.initial").click
    (
	function()
	{
	    _this.goToPage(pageIndex);
	}
    );

    /*
       On charge la première page
    */

    this.goToPage(pageIndex);

    /*
       On charge la première page
    */

    this.loadPage(this.nbPages);
};

wptn.navigation.prototype.next = function()
{
    if ( !this.goToPage(this.pageIndex+1) )
    {
	this.boundaryEffect(1);
    }
};

wptn.navigation.prototype.first = function()
{
    if ( !this.goToPage(1) )
    {
	this.boundaryEffect(-1);
    }
};

wptn.navigation.prototype.last = function()
{
    if ( !this.goToPage(this.nbPages) )
    {
	this.boundaryEffect(1);
    }
};

wptn.navigation.prototype.prev = function()
{
    if ( !this.goToPage(this.pageIndex-1) )
    {
	this.boundaryEffect(-1);
    }
};

wptn.navigation.prototype.boundaryEffect = function(coef)
{
    // on montre qu'on est à la fin
    var left = this._getPageOffset(this.pageIndex);
    this.pagesContainer.parent().stop(true, true)
	.animate({"scrollLeft": left + coef*10}, {duration : 100})
	.animate({"scrollLeft": left}, {duration : "fast"});
};

wptn.navigation.prototype.goToPage = function(page)
{
    // on vérifie que la page est dans les bornes
    if ( page == this.pageIndex || page <= 0 || page > this.nbPages )
    {
	return false;
    }

    var _this = this;
    this.loadPage
    (
	page, 
	function(p)
	{
	    _this.pagesContainer.parent().animate
	    (
		{"scrollLeft": _this._getPageOffset(p)}, 
		{duration : "fast"}
	    );

	    _this.pageIndex = page;

	    for ( var i = 1 ; i <= 3 ; i++ )
	    {
		_this.loadPage(page-i);
		_this.loadPage(page+i);
	    }
	}
    );

    return true;
};

wptn.navigation.prototype.loadPage = function(page, callback)
{
    if ( page <= 0 || page > this.nbPages )
    {
	if ( callback )
	{
	    callback(null); 
	}

	return;
    }

    var p = this.loadedPages[page-1];
    if ( p )
    {
	if ( callback )
	{
	    callback(p);
	}

	return;
    }

    this.synchronize
    (
	function()
	{
	    /*
		On prépare la page
	    */
	    this.loadedPages[page-1] = p = {index:page, loaded:false};
	    p.container = jQuery(document.createElement("div")).addClass("page loading page-" + page).css(this.pageCss);

	    /*
	       On cherche la page précédente pour l'insérer
	    */
	    var found = null;
	    for ( var i = page - 2 ; !found && i >= 0 ; found = this.loadedPages[i--] );
	    p.container.insertAfter(found ? found.container : this.before);

	    /*
	       On met à jour la width et
	       la position du container
	    */

	    this._updateWidthAndPos();

	    /*
	       Et enfin on charge la page
	    */
	    var _this = this;
	    p.container.load
	    (
		wptn.pluginURL + "wptn_page", {page:page, selectedPostId:this.selectedPostId},
		function()
		{
		    p.loaded = true;
		    _this._initPage(this);
		}
	    );

	    if ( callback ) 
	    {
		callback(p);
	    }
	}
    );
};

wptn.navigation.prototype._initPage = function(container)
{
    var _this = this;

    jQuery(container).removeClass("loading").find("li.post").css("float", "left")
    .mouseenter
    (
	function()
	{
	    _this.preview.html(jQuery(this).html()).stop(true)
	    .show().fadeTo("fast", 1, function(){jQuery(this).css("filter", "")});
	}
    )
    .mouseleave
    (
	function()
	{
	    _this.preview.html(jQuery(this).html()).stop(true)
	    .fadeTo("slow", 0, function(){jQuery(this).hide()});
	}
    );

    jQuery(wptn).trigger("pageLoaded", this, container);
};


wptn.navigation.prototype._createPageFromDom = function(pageContainer)
{
    pageContainer = jQuery(pageContainer);

    /*
       On tente de déterminer 
       l'index de la page
    */

    var preamble = "page-";
    var index = -1;

    var classNames = (pageContainer.get(0).className || "").split(/\s+/);
    for ( var i = 0 ; i < classNames.length ; i++ )
    {
	if ( classNames[i].substr(0, preamble.length) == preamble )
	{
	    index = classNames[i].substr(preamble.length);
	    break;
	}
    }

    if ( index < 0 )
    {
	return;
    }

    pageContainer.css(this.pageCss);

    var page = this.loadedPages[index-1] = {index:index, loaded:true, container:pageContainer};
    this._initPage(pageContainer);

    return page;
};

// si la page Index on prends la page courrante
wptn.navigation.prototype._updateWidthAndPos = function(page)
{
    // on calcule la taille du container
    var length = 0;
    this.pagesContainer.children().each
    (
	function()
	{
	    length += jQuery(this).width();
	}
    );

    this.pagesContainer.width(length); 

    /*
	On repositionne le scroll 
    */

    offset = (!page? this._getCurrentOffset() : this._getPageOffset(page));

    var parent = this.pagesContainer.parent();
    parent.scrollLeft(offset);
};

wptn.navigation.prototype._getCurrentOffset = function()
{
    return this._getPageOffset(this.pageIndex);
};

wptn.navigation.prototype._getPageOffset = function(page)
{
    if ( typeof(page) == "number")
    {
	page = this.loadedPages[page-1];
    }

    if ( page )
    {
	return (page.container.offset().left - this.before.offset().left);
    }

    return 0;
};

wptn.navigation.prototype.synchronize = function(callback)
{
    var _this = this;
    this.pagesContainer.parent().synchronize
    (
	function()
	{
	    callback.call(_this);
	}
    );
};

jQuery.fn.extend
({
    // log dans la console cet objet
    log : function()
    {
	if ( console )
	{
	    console.log(this);
	}

	return this;
    },

    // synchronize une fonction sur le monitor portée par l'objet jquery
    synchronize : function(name, callback)
    {
        if ( typeof name !== "string" )
        {
            callback = name;
            name = "fx";
        }

	var _this = this;
        var f = function()
        {
            if ( callback )
            {
                callback.call(_this);
            }

            jQuery(_this).dequeue(name);
        }

        return this.each
        (
            function()
            {
                var queue = jQuery.queue(this, name, f);
                if( queue.length == 1 )
                {
                    jQuery.dequeue(this, name);
                }
            }
        );
    }
});
