vanilla.namespace('mojo.resaski.devis');

/*
   Dates step
*/

mojo.resaski.devis.dates =
{
    view : null,

    init : function(properties)
    {
	this.view = $("#view-" + properties.viewId);

	/*
	   Initialisation du calendrier
	*/

	mojo.resaski.devis.calendar.init(this.view);

	/*
	   On initialise les évènements sur les date fields
	*/

	var _this = this;
	$("div.fieldContainer select", this.view).change
	(
	    function()
	    {
		var from = $("div.dateFrom select", _this.view);
		var to = $("div.dateTo select", _this.view);

		var beginDate = from.val();
		var endDate = to.val();

		if ( mojo.resaski.devis.calendar.dateToId(beginDate) > mojo.resaski.devis.calendar.dateToId(endDate) )
		{
		    endDate = null;
		}

		if ( from.get(0) == this && !endDate )
		{
		    endDate = beginDate;
		}

		from.val(beginDate);
		to.val(endDate);

		mojo.resaski.devis.calendar.selectPeriod(beginDate, endDate);
	    }
	)
	.change();
    },

    updatePopups : function(begin, end)
    {
	if ( !end )
	{
	    end = begin;
	}

	$("div.dateFrom select", this.view).val(begin);
	$("div.dateTo select", this.view).val(end);
    }
};


mojo.resaski.devis.calendar =
{
    content	: null,
    months	: null,

    firstDay	: null,
    lastDay	: null,
    pageIndex	: 0,
    marginWidth	: 30,

    init : function(view)
    {
	this.content = $("div.calendar div.calendar-content", view);
	this.months  = $("div.calendar-month", this.content);

	/*
	   on ajoute un div avant et après
	*/

	this.content.append($(document.createElement("div")).css({"float":"left", width:this.marginWidth+this.months.outerWidth(), height:1}));
	this.content.prepend($(document.createElement("div")).css({"float":"left", width:this.marginWidth, height:1}));

	/*
	   On calcul la width du container
	*/

	this.content.width(this.months.outerWidth()*(this.months.length+1) + this.marginWidth*2);

	/*
	   On gère les évènements
	*/

	$("table td:not(.disabled)", this.content).click
	(
	    function()
	    {
		mojo.resaski.devis.calendar.selectDay(this.id);
	    }
	);

	$("div.calendarContainer a.next", view).click
	(
	    function()
	    {
		mojo.resaski.devis.calendar.nextPage();
	    }
	);

	$("div.calendarContainer a.previous", view).click
	(
	    function()
	    {
		mojo.resaski.devis.calendar.previousPage();
	    }
	);

	// on va sur la première page
	this.gotoPageByIndex(0, true);
    },

    selectPeriod : function(begin, end)
    {
	if ( begin )
	{
	    this.gotoMonth(parseInt(begin.split('/')[1], 10));
	}
	
	this.firstDay	= this.dateToId(begin);
	this.lastDay	= this.dateToId(end);

	this.computePeriod();
    },

    selectDay : function(id)
    {
	if ( !this.firstDay || this.lastDay )
	{
	    this.firstDay   = id;
	    this.lastDay    = null;
	}
	else if ( id > this.firstDay )
	{
	    this.lastDay = id;
	}
	else 
	{
	    this.lastDay    = this.firstDay;
	    this.firstDay   = id;
	}

	this.computePeriod();
	mojo.resaski.devis.dates.updatePopups(this.idToDate(this.firstDay), this.idToDate(this.lastDay));
    },

    idToDate : function(v)
    {
	if ( !v )
	{
	    return "";
	}

	var d = v.split('-');
	d.shift();

	var t = d[0];
	d[0] = d[2];
	d[2] = t;

	return d.join('/');
    },

    dateToId : function(v)
    {
	if ( !v )
	{
	    return null;
	}

	var d = v.split('/');
	var t = d[0];
	d[0] = d[2];
	d[2] = t;

	return "day-" + d.join('-');
    },

    clearPeriod : function()
    {
	this.content.stop(true);
	$("td", this.content).removeClass("selected first last");
    },

    computePeriod : function()
    {
	this.clearPeriod();

	if ( !this.firstDay )
	{
	    return;
	}

	if ( !this.lastDay )
	{
	    $("#" + this.firstDay).addClass("selected first last");
	}
	else 
	{
	    // on récupère les tds à animer
	    var _this = this;
	    var tds = $("td", this.content).filter
	    (
		function()
		{
		    return (this.id >= _this.firstDay && this.id <= _this.lastDay);
		}
	    );

	    var i = 0;

	    this.content.css({index:0}).animate	
	    (
		{
		    index : tds.length - 1
		},
		{
		    duration : 10*tds.length,
		    step : function(index)
		    {
			index = Math.floor(index);
			for ( ; i <= index ; i++ )
			{
			    var td = $(tds.get(i)).addClass("selected");
			    if ( td.attr("id") == _this.firstDay )
			    {
				td.addClass("first");
			    }
			    
			    if ( td.attr("id") == _this.lastDay )
			    {
				td.addClass("last");
			    }
			}
		    }
		}
	    );
	}
    },

    gotoMonth  : function(num)
    {
	var index = 0;
	this.months.each
	(
	    function(i)
	    {
		if ( $(this).is("#calendar-month-" + num) )
		{
		    index = i;
		    return false;
		}

		return true;
	    }
	);

	this.gotoPageByIndex(Math.floor(index/2));
    },

    gotoPageByIndex : function(i, doNotAnimate)
    {
	var nbPages = Math.floor(this.months.length/2 + (this.months.length%2));
	if ( i >= 0 && i < nbPages )
	{
	    var x = this._getPageOffset(i);
	    if ( doNotAnimate )
	    {
		this.content.parent().scrollLeft(x);
	    }
	    else
	    {
		this.content.parent().stop(true).animate({scrollLeft:x}, {duration:800,easing:"easeInOutBack"});
	    }

	    this.pageIndex = i;
	    return true;
	}

	return false;
    },

    _getPageOffset : function(i)
    {
	return i*this.months.outerWidth()*2 + this.marginWidth;
    },

    nextPage : function()
    {
	if ( !this.gotoPageByIndex(this.pageIndex+1) )
	{
	    this.boundaryEffect(1);
	}
    },

    previousPage : function()
    {
	if ( !this.gotoPageByIndex(this.pageIndex-1) )
	{
	    this.boundaryEffect(-1);
	}
    },

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

/*
    infos step
*/

mojo.resaski.devis.infos =
{
    init : function(properties)
    {
	var view = $("#view-" + properties.viewId);

	// suppression d'une personne
	$("table.personnes td a.remove", view).click
	(
	    function()
	    {
		if ( $(this).closest("tbody").find("tr").length > 1 )
		{
		    $(this).closest("tr").remove();	
		}
	    }
	);

	// ajout d'une personne
	$("a.add", view).click
	(
	    function()
	    {
		var tbody = $("table.personnes tbody");
		var line = $("tr", tbody).slice(0, 1).clone(true).appendTo(tbody);
		line.find("select, input").val("");
		line.find("input.idField").val(-1);
	    }
	);

	// validation du formulaire
	$("form", view).submit
	(
	    function(e)
	    {
		var nbPersonnes = 0;

		// pour chaque ligne on vérifie
		$(this).find("table.personnes tr.line").each
		(
		    function()
		    {
			// on récupères les champs de la ligne
			var fields = $(this).find("input, select").not("[type=hidden]").not("[name*=sexe]");

			var nbFill = 0;
			fields.each( function() { nbFill += $(this).val() ? 1 : 0 } );

			// aucun champs n'est rempli, cette ligne est vide
			if ( nbFill == 0 )
			{
			    return;
			}

			// une personne a été renseignée
			nbPersonnes++;

			// est-ce que tous les champs sont renseignés ?
			if ( nbFill < fields.length )
			{
			    alert(__('Tous les champs d\'une personne sont obligatoires'));
			    e.preventDefault();
			    return false;
			}

			// est-ce que les champs entiers sont renseignés
			fields = fields.filter("[name*=age], [name*=poids], [name*=taille], [name*=pointure]").filter
			(
			    function()
			    {
				var v = parseInt($(this).val(), 10);	
				return (isNaN(v) || v <= 0);
			    }
			);

			if ( fields.length > 0 )
			{
			    alert(__('Les champs age, poids, taille et pointure doivent être des entiers strictement positifs'));
			    e.preventDefault();
			    return false;
			}
		    }
		);

		if ( !nbPersonnes )
		{
		    alert(__('Merci de définir au moins une personne'));
		    e.preventDefault();
		}
	    }
	);
    }
}

/*
   Matériel step
*/

mojo.resaski.devis.materiel =
{
    marginWidth : 30,
    packTarifs : [],
    packIndex : -1,
    packs : null,
    priceFormat : null,

    init : function(properties, priceFormat)
    {
	this.view = $("#view-" + properties.viewId);
	this.priceFormat = priceFormat;
	this.packs = this.view.find("div.pack");

	// FIXME safari ne récupère pas la taille correct des packs lorsqu'on fait un history back ?

	this.content = this.packs.wrapAll('<div class="packsContent"></div>').parent();

	/*
	   on ajoute un div avant et après
	*/

	this.content.append($(document.createElement("div")).css({"float":"left", width:this.marginWidth, height:1}));
	this.content.prepend($(document.createElement("div")).css({"float":"left", width:this.marginWidth, height:1}));

	/*
	   On calcul la width du container
	*/

	this.content.width(this.packs.outerWidth()*this.packs.length + this.marginWidth*2);

	/*
	   Initialisation du slider
	*/

	$("a.next", this.view).click
	(
	    function()
	    {
		mojo.resaski.devis.materiel.nextPack();
	    }
	);

	$("a.previous", this.view).click
	(
	    function()
	    {
		mojo.resaski.devis.materiel.previousPack();
	    }
	);

	/*
	   On grise chaussures seules si sans chaussures est sélectionné
	*/

	var f = function()
	{
	    if ( !this.checked )
	    {
		return;
	    }

	    var i = $(this);
	    var c = i.closest("ul.chaussures");
	    var b = c.find("input[type=checkbox]");

	    if ( i.val() == "sans" )
	    {
		b.attr("disabled", "disabled").attr("checked", "");
	    }
	    else
	    {
		b.attr("disabled", "");
	    }
	};

	this.view.find("div.pack ul.chaussures input[type=radio]").click(f).change(f).change();

	/*
	    On bind les radio et checkbox
	*/

	this.view.find("div.pack ul input").click
	(
	    function()
	    {
		mojo.resaski.devis.materiel.updateTarifsAndImages($(this).closest("div.pack"));
	    }
	);

	/*
	   Par défaut on update tous les packs
	*/

	this.view.find("div.pack").each
	(
	    function()
	    {
		mojo.resaski.devis.materiel.updateTarifsAndImages($(this));
	    }
	);

	// on défile jusqu'au selected pack
	var selected = this.view.find("div.pack.selected");
	if ( selected )
	{
	    this.gotoPack(selected, true);
	}
	else
	{
	    this.goToBackByIndex(0, true);
	}

    },

    addPackTarif : function(tarif)
    {
	this.packTarifs.push(tarif);

	// on préload les images des chaussres
	$.each
	(
	    tarif.chaussures,
	    function()
	    {
		new Image().src = this.image;
	    }
	)
    },

    nextPack : function()
    {
	if ( !this.gotoPackByIndex(this.packIndex+1) )
	{
	    this.boundaryEffect(1);
	}
    },

    previousPack : function()
    {
	if ( !this.gotoPackByIndex(this.packIndex-1) )
	{
	    this.boundaryEffect(-1);
	}
    },

    gotoPack : function(pack, doNotAnimate)
    {
	pack = $(pack).get(0);
	var index = 0;
	this.packs.each
	(
	    function(i)
	    {
		if ( this == pack )
		{
		    index = i;
		    return false;
		}

		return true;
	    }
	);

	this.gotoPackByIndex(index, doNotAnimate);
    },

    gotoPackByIndex : function(i, doNotAnimate)
    {
	if ( i >= 0 && i < this.packs.length )
	{
	    var x = this._getPackOffset(i);
	    if ( doNotAnimate )
	    {
		this.content.parent().stop(true).scrollLeft(x);
	    }
	    else
	    {
		this.content.parent().stop(true).animate({scrollLeft:x}, {duration:800,easing:"easeInOutBack"});
	    }

	    this.packIndex = i;
	    return true;
	}

	return false;
    },

    _getPackOffset : function(i)
    {
	return i*this.packs.eq(0).outerWidth() + this.marginWidth;
    },

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

    updateTarifsAndImages : function(pack)
    {
	// on récupère l'id du pack et les tarifs
	var id	    = pack.find("input[type=hidden][name*=packId]").val();
	var tarifs  = this.findTarifByPackId(id);

	// on récupère la chaussure sélectionnée
	var chaussureId		= pack.find("ul.chaussures input[type=radio]:checked").val();
	var sansChaussures	= (chaussureId == "sans" ? true : false);
	var chaussuresSeules	= pack.find("ul.chaussures input[type=checkbox]").is(":checked");

	// on récupère les options sélectionnées
	var options		= pack.find("ul.options input[type=checkbox]:checked");

	// on détermine le prix du pack
	var prix = this.getPriceFor(tarifs, sansChaussures, chaussuresSeules, chaussureId);

	/*
	   On met à jour les prix des suppléments
	*/
	
	var _this = this;
	var pf = this.priceFormat;
	pack.find("ul.chaussures input").each
	(
	    function()
	    {
		var i = $(this);	
		var v = i.val();
		var p = 0;
		
		if ( v == "sans" )
		{
		    p = _this.getPriceFor(tarifs, true);
		}
		else if ( i.is("[type=checkbox]") )
		{
		    p = _this.getPriceFor(tarifs, false, true, (sansChaussures ? tarifs.chaussureId : chaussureId));
		}
		else
		{
		    p = _this.getPriceFor(tarifs, false, chaussuresSeules, v);
		}

		p -= prix;
		if ( p == 0 )
		{
		    i.closest("li").find("span.supplement").html(__('Inclus dans le prix'));
		}
		else
		{
		    var neg = p < 0;
		    p = Math.abs(p / 100);
		    i.closest("li").find("span.supplement").html(!neg ? __('+ %1%', vanilla.text.number.format(p, pf)) : __('- %1%', vanilla.text.number.format(p, pf)));
		}
	    }
	);

	// on ajoute le prix des options
	$.each
	(
	    options,
	    function()
	    {
		prix += _this.findTarifByOptionId(tarifs, $(this).val()).prix;
	    }
	);

	pack.find("div.prix span").html(vanilla.text.number.format(prix / 100, pf));

	/*
	   On met à jour les images
	*/

	if ( chaussureId == "sans" )
	{
	    pack.find("div.resume div.chaussure.img img").hide();
	}
	else
	{
	    var chaussure = this.findTarifByChaussureId(tarifs, chaussureId);
	    pack.find("div.resume div.chaussure.img img").show().attr("src", chaussure.image);
	}

	pack.find("div.resume div.glisse.img img").toggle(!chaussuresSeules);
    },

    getPriceFor : function(tarifs, sansChaussures, chaussuresSeules, chaussureId)
    {
	if ( sansChaussures )
	{
	    // on récupère seulemement le prix de la glisse
	    return tarifs.prixGlisse;
	}
	else if ( chaussuresSeules )
	{
	    // on récupère seulemement le prix de la chaussure
	    return this.findTarifByChaussureId(tarifs, chaussureId).prix;
	}
	else if ( chaussureId != tarifs.chaussureId )
	{
	    // on récupère seulemement le prix de la chaussure + le prix de la glisse
	    return tarifs.prixGlisse + this.findTarifByChaussureId(tarifs, chaussureId).prix;
	}

	// le prix du pack
	return tarifs.prixPack;
    },

    findTarifByPackId : function(id)
    {
	for ( var i = 0 ; i < this.packTarifs.length ; i++ )
	{
	    var t = this.packTarifs[i];
	    if ( t.packId == id )
	    {
		return t;
	    }
	}

	return null;
    },

    findTarifByChaussureId : function(tarifs, id)
    {
	for ( var i = 0 ; i < tarifs.chaussures.length ; i++ )
	{
	    var t = tarifs.chaussures[i];
	    if ( t.id == id )
	    {
		return t;
	    }
	}

	return null;
    },

    findTarifByOptionId : function(tarifs, id)
    {
	for ( var i = 0 ; i < tarifs.options.length ; i++ )
	{
	    var t = tarifs.options[i];
	    if ( t.id == id )
	    {
		return t;
	    }
	}

	return null;
    }
};
