vanilla.namespace('com.alteneve.devis');

com.alteneve.devis =
{
    popups : [],

    addLine : function(name)
    {
	var lines = this.getLines(name);

	// on récupère la ligne de référence et on la clone
	var newLine = lines[0].cloneNode(true);

	// on efface les valeurs
	Arr(newLine.getElementsByTagName("input")).forEach
	(
	    function(input)
	    {
		input.value = "";
	    }
	    .bind(this)
	);

	this.getContainer(name).appendChild(newLine);
    },

    removeLine : function(name, line)
    {
	var lines = this.getLines(name);
	if ( lines.length <= 1 )
	{
	    return;
	}

	this.getContainer(name).removeChild(line);
    },

    getLines : function(name)
    {
	return Arr(this.getContainer(name).getElementsByTagName("li"));
    },

    getContainer : function(name)
    {
	return EL(name + "-personnes");
    },

    onDateFromChange : function(name)
    {
	this.updatePeriod(name);
	this.onDateChange(name);
    },

    updatePeriod : function(name)
    {
	var dateFromField   = EL(name + '-dateFrom');
	var dateToField	    = EL(name + '-dateTo');

	var dateToPopup	    = this.getPopup(dateToField);
	var option	    = vanilla.html.Form.Popup.getSelectedOption(dateFromField);

	dateToField.selectedIndex = -1;

	// on efface toute les options du dateTo
	Arr(dateToField.getElementsByTagName("optgroup")).forEach(function(e){e.parentNode.removeChild(e)});

	if ( !option.value )
	{
	    // on remet toute les options
	    Arr(dateFromField.getElementsByTagName("optgroup")).forEach
	    (
		function(group)
		{
		    dateToField.appendChild(dateToPopup.groups[group.label].cloneNode(true));
		}
	    );

	    vanilla.html.Form.setFieldValue(dateToField, "");
	}
	else
	{
	    var fromGroup   = option.parentNode;
	    var toSrcGroup  = dateToPopup.groups[fromGroup.label]; 
	    var toDestGroup = toSrcGroup.cloneNode(false);

	    var indexInGroup = 0;
	    var fromGroupOptions = Arr(fromGroup.getElementsByTagName('option'));
	    for ( ; indexInGroup < fromGroupOptions.length && fromGroupOptions[indexInGroup] != option ; indexInGroup++ );

	    Arr(toSrcGroup.getElementsByTagName("option")).forEach
	    (
		function(opt, i)
		{
		    if ( i >= indexInGroup )
		    {
			toDestGroup.appendChild(opt.cloneNode(true));
		    }
		}
	    );

	    dateToField.appendChild(toDestGroup);
	    // ?? ne marche pas sous opéra !!?
	    // vanilla.html.Form.setFieldValue(dateToField, toDestGroup.firstChild.value);
	}
    },

    onDateChange : function(name)
    {
	var dateFromField   = EL(name + '-dateFrom');
	var dateToField	    = EL(name + '-dateTo');

	var from    = vanilla.html.Form.Popup.getSelectedOption(dateFromField);
	var to	    = vanilla.html.Form.Popup.getSelectedOption(dateToField);

	saisonId    = -1;
	dateFrom    = null;
	dateTo	    = null;

	if ( to && to.value )
	{
	    saisonId	= to.parentNode.id.split('-').last();
	    dateTo	= to.value;
	}

	if ( from && from.value )
	{
	    saisonId	= from.parentNode.id.split('-').last();
	    dateFrom	= from.value;
	}

	this.calendar.selectPeriod(name, saisonId, dateFrom, dateTo);
    },

    getPopup : function(field)
    {
	if ( !this.popups[field.id] )
	{
	    this.savePopup(field);
	}

	return this.popups[field.id];
    },

    savePopup : function(field)
    {
	var popup = 
	{
	    id	    : field.id, 
	    groups  : []
	}

	Arr(field.getElementsByTagName("optgroup")).forEach
	(
	    function(optgroup)
	    {
		popup.groups[optgroup.label] = optgroup.cloneNode(true);
	    }
	);

	this.popups[field.id] = popup;
    },

    back : function(form, url)
    {
	form.action = url;
	form.submit();
    }
};

com.alteneve.devis.calendar =
{
    saisonId	: -1, 
    months	: null,

    firstDay	: null,
    lastDay	: null,
    pageIndex	: -1,

    onSaisonChange : function(name)
    {
	this.selectSaison(vanilla.html.Form.getFieldValue(name + "-saison"));

	this.firstDay = null;
	this.lastDay = null;

	this.updatePopups(name);
    },

    selectSaison : function(id, name)
    {
	if ( id == this.saisonId )
	{
	    return;
	}

	if ( this.saisonId > 0 )
	{
	    this.clearPeriod();
	}

	var last = this.saisonId;
	this.saisonId	= id;
	this.months	= [];

	vanilla.html.Form.setFieldValue("devis-saison", this.saisonId);
    
	// on récupère les mois
	for ( var child = EL("calendar-saison-content-" + this.saisonId).firstChild ; child ; child = child.nextSibling )
	{
	    if ( vanilla.html.DOM.hasClassName(child, "calendar-month") )
	    {
		this.months.push(child.id);
	    }
	}

	this.scrollToSaison(last > 0);
	this.gotoPageByIndex(0, true);
    },

    selectPeriod : function(name, saisonId, begin, end)
    {
	if ( saisonId > 0 )
	{
	    this.selectSaison(saisonId, name); 
	}

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

	this.computePeriod();
    },

    selectDay : function(id, name)
    {
	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.updatePopups(name);
	this.computePeriod();
    },

    updatePopups : function(name)
    {
	vanilla.html.Form.setFieldValue(name + "-dateFrom", this.idToDate(this.firstDay));
	com.alteneve.devis.updatePeriod(name);
	vanilla.html.Form.setFieldValue(name + "-dateTo",	this.idToDate(this.lastDay));
    },

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

	var d = v.split('-');
	d.removeAtIndex(0);

	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()
    {
	if ( this.periodAnimation )
	{
	    this.periodAnimation.stop();
	}

	Arr(EL("calendar-saison-content-" + this.saisonId).getElementsByTagName("td")).forEach
	(
	    function(td)
	    {
		vanilla.html.DOM.removeClassName(td, "selected");
		vanilla.html.DOM.removeClassName(td, "first");
		vanilla.html.DOM.removeClassName(td, "last");
	    }
	    .bind(this)
	);
    },

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

	if ( !this.firstDay )
	{
	    return;
	}

	if ( !this.lastDay )
	{
	    vanilla.html.DOM.addClassName(this.firstDay, "selected first last");
	}
	else 
	{
	    var tds1 = Arr(EL("calendar-saison-content-" + this.saisonId).getElementsByTagName("td"));
	    var tds2 = [];
	    for ( var i = 0 ; i < tds1.length ; i++ )
	    {
		var td = tds1[i];
		if ( td.id >= this.firstDay && td.id <= this.lastDay )
		{
		    tds2.push(td);
		}
	    }

	    var last = 0;

	    this.periodAnimation = new vanilla.animation.Animation(0, tds2.length-1);
	    this.periodAnimation.onNextValue.subscribe
	    (
	        function(index)
	        {
		    index = Math.round(index);
		    for ( var i = last ; i <= index ; i++ )
		    {
			var td = tds2[i];

			vanilla.html.DOM.addClassName(td, "selected");

			if ( td.id == this.firstDay )
			{
			    vanilla.html.DOM.addClassName(td, "first");
			}
			
			if ( td.id == this.lastDay )
			{
			    vanilla.html.DOM.addClassName(td, "last");
			}
		    }
	        }
	        .bind(this)
	    );

	    this.periodAnimation.duration = 0.1;
	    this.periodAnimation.start();
	}

    },

    gotoMonth  : function(num)
    {
	var index = this.months.indexOf("calendar-month-" + num);
	this.gotoPageByIndex(Math.floor(index/2));
    },

    gotoPageByIndex : function(i, doNotAnimate)
    {
	nbPages = Math.floor(this.months.length/2 + (this.months.length%2));

	if ( doNotAnimate )
	{
	    if ( i >= 0 && i < nbPages )
	    {
		this.scrollSaisonDivTo(i*EL(this.months[0]).clientWidth*2+10);
		this.pageIndex = i;
	    }
	}
	else if ( !this.monthAnimation || !this.monthAnimation.isAlive() )
	{
	    var start = this.getSaisonDiv().scrollLeft;

	    if ( i < 0 )
	    {
		this.monthAnimation = new vanilla.animation.Animation(0, 20);
		this.monthAnimation.onNextValue.subscribe
		(
		    function(value)
		    {
			if ( value < 10 )
			{
			    this.scrollSaisonDivTo(start - value);
			}
			else
			{
			    this.scrollSaisonDivTo(start - 10 + (value - 10));
			}
		    },
		    this
		);
	    }
	    else if ( i >= nbPages )
	    {
		this.monthAnimation = new vanilla.animation.Animation(0, 20);
		this.monthAnimation.onNextValue.subscribe
		(
		    function(value)
		    {
			if ( value < 10 )
			{
			    this.scrollSaisonDivTo(start + value);
			}
			else
			{
			    this.scrollSaisonDivTo(start + 10 - (value - 10));
			}
		    },
		    this
		);
	    }
	    else
	    {
		this.monthAnimation = new vanilla.animation.Animation(start, i*EL(this.months[0]).clientWidth*2+10);
		this.monthAnimation.onNextValue.subscribe(this.scrollSaisonDivTo, this);

		this.pageIndex = i;
	    }

	    this.monthAnimation.method = vanilla.animation.deceleration;
	    this.monthAnimation.duration = 0.2;
	    this.monthAnimation.start();
	}
    },

    scrollSaisonDivTo : function(x)
    {
	return this.getSaisonDiv().scrollLeft = x;
    },

    getSaisonDiv : function()
    {
	return EL("calendar-saison-" + this.saisonId);
    },

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

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

    scrollToSaison : function(animate)
    {
	var y = this.getSaisonDiv().offsetTop;

	if ( animate )
	{
	    if ( this.saisonAnimation && this.saisonAnimation.isAlive() )
	    {
		return;
	    }

	    this.saisonAnimation = new vanilla.animation.Animation(this.getCalendarDiv().scrollTop, y);
	    this.saisonAnimation.onNextValue.subscribe(this.scrollCalendarDivTo, this);
	    this.saisonAnimation.duration = 0.2;
	    this.saisonAnimation.method = vanilla.animation.deceleration;
	    this.saisonAnimation.start();
	}
	else
	{
	    this.getCalendarDiv().scrollTop = y;
	}
    },

    scrollCalendarDivTo : function(y)
    {
	return this.getCalendarDiv().scrollTop = y;
    },

    getCalendarDiv : function()
    {
	return this.getSaisonDiv().parentNode.parentNode;
    }
};

