if (typeof _trace == "undefined")
{
	_trace = function(message, args)
	{
	    var _console = window.console || false;
	    if(_console)
	    {
	        _console.log(message, (args || ""));
	    }
	};
}
/*
 * Composant : draggElement
 * Affecte un événement "onDragg à un élément"
 */
var draggElement = function(params)
{
	//this.init(elm, params);
	driver.extend(this, params);
	return this;
}
var draggkeys = [];
var currentDraggElement = null;

// FIXME : bug de référence
// Lorsque lon instancie, on met à jour les propriété de l'objet
// non de l'instance
draggElement.prototype = 
{
	"dragged": false,	
	"position": [0,0],
	"elm": false,

	"minWidth": 0,
	"maxWidth": 0,
	
	"onDragg": function(position) 
	{
		/*
		_trace(this)
		_trace("(default) onDragg : " + position)
		*/
	},
	
	"setDragg": function(elm, container)
	{
		var 
			_this = this,
			_dragged = false,
			_container = this.container
		;
		
		driver.addEvent(elm, 'mousedown', function(e)
		{
			e.preventDefault();
			
			var elm = this;
			_container.currentDraggElement = elm;			
			_this.onDragg.call(_this, _this.getPosition(e, _container.currentDraggElement));	
			
		});
		
		if (!(_container.isDraggable || false))
		{
			_container.isDraggable = true;

			// Arret du Dragg
			driver.addEvent(_container, 'mouseup', function(e)
			{
				this.currentDraggElement = null;
			});
			driver.addEvent(_container, 'mousemove', function(e)
			{
				e.preventDefault();
				if (this.currentDraggElement)
				{
					_this.onDragg.call(_this, _this.getPosition(e, this.currentDraggElement));
				}
			});
		}
	},
	
	"getPosition": function(e, elm)
	{
		if (typeof elm == "undefined" || !elm)
		{
			return false;
		}
		var
			_elm = elm,
			_minX = this.minWidth,
			_maxX = this.maxWidth,
			
			/*
			_posX = ((typeof e.layerX == "undefined") ? e.offsetX : e.layerX) + _minX,
			_posX = (_posX > _maxX) ? _maxX : ((_posX < _minX) ? _minX : _posX), // calcul des bornes
			_posY = (typeof e.layerY == "undefined") ? e.offsetY : e.layerY
			*/			
			_posX = e.pageX,
			_posY = e.pageY
		;
		
		return [_posX, _posY];
	},
	
	"init": function(elm, container)
	{
		/*
		_trace("--")
		_trace("New Dragg Element " + this.params.maxWidth)
		*/
		
		//this.params.maxWidth = elm.offsetWidth;
		if (!elm || !container)
		{
			return false;
		}
		
		this.elm = elm;		
		this.container = container;
		this.setDragg(this.elm);
	}
}

/*
 * Module : view360
 * Vision 360* d'une image
 * => transforme l'image en DraggElement
 * => update de la source de l'iamge en fonction de la position de la souris
 * => !!! Fournir x sources de l'image
 */

var view360 = function(params)
{
	//this.init(elm, params);
	driver.extend(this.params, params);
	return this;
}
	
view360.prototype = 
{
	"className": 
	{
		content: "media360-item"
	},
	
	"indice": 0,	
	"draggElement": false,
	"params":
	{
		maxLength: 36
	},

	"handleDragg": function(position)
	{
		var
			_position = this.position || [0,0],
			_newPosition = position[0],
			_oldPosition = _position[0],
			
			_minIndice = 1,
			_maxIndice = this.params.maxLength,
			
			_indice = this.indice
		;		
		var
			_indice = (_oldPosition > _newPosition) ? --_indice : ((_oldPosition < _newPosition) ? ++_indice : _indice),
			_indice = (_indice < _minIndice) ? _maxIndice : ((_indice > _maxIndice) ? _minIndice : _indice)
		;
		
		if (this.indice == _indice)
		{
			return false;
		}
		
		// Mise à jour du contenu
		this.updateContent(this.elm, _indice);
		
		// Mise à jour ddes propriétés
		this.indice = _indice;
		this.position = position;	
	},
	
	"updateContent": function(elm, value)
	{
		if (typeof elm == "undefined"|| !elm)
		{
			return false;
		}		
		elm.src = (elm.src || "").replace(/_\d+/, "_" + value);		
		return true;
	},
	
	"loadContent": function()
	{
		var tmp = new Image();
		tmp.src = this.elm.src;
		for(var i=1, len=this.params.maxLength; i<len; i++)
		{
			this.updateContent(tmp, i+1);
		}
	},
	
	"init": function(elm, params)
	{
		if (typeof elm == "undefined" || !elm) 
		{
			return false;
		}

		var _contentElm = driver.find(elm, '.' + this.className["content"]);
		if (!_contentElm.length || !_contentElm[0])
		{
			return false;
		}
		
		this.indice = 1;
		this.elm = _contentElm[0];
		
		// Rendre le contenu Draggable
		var _this = this;		
		var plop = new draggElement(
		{
			"maxWidth": elm.offsetWidth,
			"onDragg": function(position)
			{
				_this.handleDragg.call(_this, position);
			}
		});
		plop.init(this.elm)
		
		// Préchargement des images
		// FIXME : lorsque lon chargera une nouvelle slide : 
		// lancer le préchargement si ça n'a pas déjà été fait
		this.loadContent();
	}
}


/*
 * Composant : scrollElement
 * Simule une fausse barre de scroll dans un container donné
 * => Identifier le container, et la barre de scroll
 * => Effet CSS : bouger la position d'un backgroundImage dans la barre de scroll
 */
var scrollElement = function(params)
{
	this.pas = params.buttonWidth || 0;
	this.suffixe = params.defaultPosition || "px 0";
	
	return this;
}

scrollElement.prototype = 
{
	"initialized": false,
	
	"className":
	{
		"menu": "dragg-menu",
		"disable": "disabled",
		"content": "dragg-content",
		"scroll": "scroll-content"
	},
	
	"handleScroll" : function(position)
	{
		var
			_elm = this.buttonElm,
			_suffixe = this.suffixe,
			_defaultPosition = this.contentElm.cumulativeOffset(),
			_left = (position[0] - _defaultPosition[0]),
			
			_max = this.contentElm.offsetWidth-20,
			_left = (_left<0) ? 0 : _left,
			_left = (_left>_max) ? _max : _left,	
			_newBackgroundPosition = _left + _suffixe,
			_backgroundPosition = _elm.backgroundPosition || (_elm.scrollLeft + _suffixe)
		;
		
		if (_backgroundPosition == _newBackgroundPosition)
		{
			return false;
		}
		this.contentElm.scrollLeft = Math.floor(_left*this.pas);
		
		//this.contentElm.scrollLeft = _left;
		_elm.style.backgroundPosition = _newBackgroundPosition;
		this.draggElement.position = position;
	},
	
	"init": function(elm)
	{
		if (typeof elm == "undefined" || !elm)
		{
			return false;
		}
		
		driver.addClass(elm, this.className["scroll"]);

		var 
			_this = this,
			_elm = driver.getElement(elm, "." + this.className["menu"]),
			_content = driver.getElement(elm, "." + this.className["content"]),
			_pas = (_content.scrollWidth-_content.offsetWidth) / (_content.offsetWidth-20)
		;
		
		this.containerElm = elm;
		this.buttonElm = _elm;
		this.contentElm = _content;
		this.pas = _pas;

		// S'il n'y a pas de scroll, ne pas ajouter le composant
		if (_content.scrollWidth <= _elm.offsetWidth)
		{
			driver.addClass(elm, this.className["disable"]);
			return false;
		}		
		
		_this.draggElement = new draggElement(
		{
			"maxWidth": _elm.offsetWidth - this.pas,
			"onDragg": function(position)
			{
				_this.handleScroll.call(_this, position);
			}
		
		});
		this.handleScroll([Math.floor(_content.scrollLeft/_pas), 0]);

		var 
			_isDraggableContainer = this.containerElm.getAttribute("data-draggable") || this.containerElm["data-draggable"] || null,
			_draggableContainer = document.getElementById(_isDraggableContainer) || this.containerElm
		;		
		_this.draggElement.init(_elm, _draggableContainer);		
		_this.initialized = true;
	}
}

/*
 * function setProgressBar
 * Sélectionne l'étape courante dans le tunnel d'achat
 */
var setProgressBar = function(elm)
{
	if (typeof elm == "undefined" || !elm)
	{
		return false;
	}
	
	var 
		className = "active",
		elements = driver.find(elm.parentNode, ".menu-item"),
		active = -1,
		i
	;
	
	for(i=elements.length-1;i>=0;i--)
	{
		if (elements[i] == elm)
		{
			driver.addClass(elements[i], className);
			active = i;
			continue;
		}
		driver.removeClass(elements[i], className);
	}
	
	
	setProgressBarNavigation(active,elements);
	
	return true;
}

/*
 * function setProgressBar
 * Add back/continue behavior on step 2 tab navigation 
 */
var setProgressBarNavigation = function(step,elements)
{
	
	// Do nothing if need to login and not on step 2
	if (step!=1 || document.getElementById('opc-login')) {
		return;
	}
	
	for(var i=elements.length-1;i>=0;i--)
	{
		if (!elements[i]['data-id'] && i!=1) {
			elements[i]['data-id'] = i;
			elements[i].style.cursor = 'pointer';		
			driver.addEvent(elements[i], "click", function(e)
			{
				e.preventDefault();
				if (e.target['data-id'] == 0) {
					// Back behavior
					window.location = progressBarStep1URL;
				}
				else if (e.target['data-id'] == 2) {
					// Next step behavior
					var forms = window.checkoutStepByStep.forms,
						item = null,
						id = [], j, f = '';
					
					for (f in forms) {						
						item = forms[f].form.parentNode.parentNode;
							
						if ( driver.getCSS(item, 'display') == 'block') {							
							id = driver.getAttr(item, 'id');
							id = id.substring(4,id.length).split('_');						
						}						
					}
					
					for(j=id.length-1;j>=0;j--) {
						id[j] = id[j].charAt(0).toUpperCase() + id[j].substring(1,id[j].length);
					}
					
					id = id.join('');
					
					if (forms[id] && forms[id].save) {
						forms[id].save();
					}
					
				}				
			});
		}
	}	
	
}

/*
 * composant : increaseField
 * gère les boutons +/- autour d'un champs texte
 */
var increaseField = function(params)
{
	driver.extend(this, params);
	return this;
}
increaseField.prototype =
{
	"onchange": function(){},
	"setError": function()
	{
		var _container = this.field.form || null;
		if (!_container)
		{
			return false;
		}
		var 
			_idMessage = _container.id + "-error" || "message-error",
			_messageElement = document.getElementById(_idMessage) || null,
			_texteError = _container.getAttribute("data-error") || "Erreur", 
			_contentElement = driver.getElement(_container, ".data-table")
		;
		if (!_messageElement && _contentElement)
		{
			_messageElement = document.createElement("div");
			_messageElement.id = _idMessage;
			_messageElement.className = "messages error";
			_container.insertBefore(_messageElement, _contentElement)
		}
		_messageElement.innerHTML = "";
		_messageElement.appendChild(document.createTextNode(_texteError));
		
	},
	"resetError": function()
	{
		var _container = this.field.form || null;
		if (!_container || !_container.id || !document.getElementById(_container.id + "-error"))
		{
			return false;
		}
		document.getElementById(_container.id + "-error").innerHTML = "";
	},
	"methods":
	{
		"increase" : function()
		{
			var 
				_field = this.field,
				_maxValue = _field.getAttribute("data-max") || 10
			;
			if (_field.value < _maxValue)
			{
				this.resetError();
				_field.value = _field.value*1+1;
				return true;
			}
			this.setError();
			return false;
		},
		"decrease" : function()
		{
			var 
				_field = this.field,
				_minValue = _field.getAttribute("data-min") || 0
			;
			if (_field.value > _minValue)
			{
				this.resetError();
				_field.value = _field.value*1-1;
			}
		}
	},
	"init" : function(elm)
	{
		var 
			_buttons = driver.find(elm, ".updateQty-button"),
			_field = driver.getElement(elm, ".qty"),
			_this = this
		;
		if (!_field)
		{
			return false;
		}
		this.field = _field;
		for (var i=0, len=_buttons.length; i<len; i++)
		{
			var _button = _buttons[i];
			driver.addEvent(_button, "click", function(e)
			{
				var 
					_action = this.getAttribute("data-action"),
					_method = _this.methods[_action] || null
				;
				if (_method && typeof _method == "function")
				{
					e.preventDefault();
					_method.call(_this);
				}
			});
			driver.addEvent(_button, "blur", function(e)
			{
				/*
				var 
					_fieldName = this.getAttribute("data-field") || this["data-field"] || "",
					_fieldCurrent = document.getElementById(_fieldName) || null
				;				
				if (_fieldCurrent != _field)
				{
				*/
					setTimeout(_this.onchange.bind(_this), 10);
					/*
				}
				*/
			});
		}
	}
}

/*
 * composant : TabElement
 * Affichage d'un contenu en fonction de son onglet
 */
var TabElement = function(params)
{
	driver.extend(this, params);
	return this;
}
TabElement.prototype = 
{
	"getAction": function()
	{
		return driver.hasClass(this.container, "active") ? "close" : "open";
	},
	"showContent": function(elm, action)
	{
		var
			_classButton = "disabled",
			_classContent = "active"
		;
		// Afficher/masquer le contenu
		driver[(action == "open") ? "addClass" : "removeClass"](this.container, _classContent);
		
		// Chargement du contenu en Ajax
		if (typeof this.ajaxBox == "undefined")
		{
			var
				_href = this.container.getAttribute("data-action"),
				_target = document.getElementById(this.container.getAttribute("data-target"))
			;
			if (_target && _href)
			{
				this.ajaxBox = new ajaxBox(
				{
					"success" : function()
					{
						_handleScriptAfterOnload();
						
						// si le contenu a déjà été chargé, 
						// ne pas recherger le contenu
						this.elm.removeAttribute("data-action");
						this.elm.removeAttribute("data-target");				
					}
				});
				
				this.ajaxBox.init(this.container);
				
				if (action == "open")
				{
					this.ajaxBox.gotoContent({"target": elm});
				}
			}
		}

		// désactiver le bouton courant
		var _oldTabId = this.container.getAttribute("data-tab");
		if (_oldTabId != elm.id)
		{
			driver.removeClass(document.getElementById(_oldTabId), _classButton);
		}
		
		// Mise à jour des infos
		driver.addClass(elm, _classButton);
		this.container.setAttribute("data-tab", elm.id);
		
	},
	"init" : function(elm)
	{
		if (typeof elm == "undefined" || !elm)
		{
			return false;
		}
		
		// Sauvegarde des éléments
		this.container = elm;

		var
			_elements = driver.find(elm, "[data-tab-menu='true']"),
			_this = this
		;		
		for(var i=0, len=_elements.length; i<len; i++)
		{
			var _element = _elements[i];
			driver.addEvent(_element, "click", function(e)
			{
				e.preventDefault();

				// Tab principal
				var _action = e.target.getAttribute("data-tab-action");
				if (_action)
				{
					_this.showContent(e.target, _action);
					return false;
				}

				// Autres boutons d'activation
				var 
					_action = _this.getAction(),
					_tabElement = driver.getElement(_this.container, "[data-tab-action='" + _action + "']")
				;
				_this.showContent(_tabElement, _action);
			})
		}


		// Initialisation du contenu
		driver.addClass(elm, "tab-container");
		var _link = document.getElementById(elm.getAttribute("data-tab"));
		if (_link)
		{
			_this.showContent(_link, _link.getAttribute("data-tab-action"));
		}
	}
}
