// $Id: gallery.js 1378 2010-04-09 21:09:36Z sdalu $

/*
 * Copyright (c)  2007-2009  Stephane D'Alu
 * http://www.sdalu.com/
 */

/*
 * #cart-default
 * #thumbnail-sizer
 *
 */


YUI().use('node', 'event', 'selector-css3', 'io-base', 'json',
	  'stylesheet', 'anim', 'cookie', 'slider', 'base', 
	  'datatype-number', 'datatype-date',
	  'easy-node', 'node-extra', 'myweb', function(Y) {

//== Localization ======================================================

var l10n = {};
l10n.fr = {
    trash_ref_q : 'Supprimer toutes les commandes relatives à la photo N°{0}?',
    cart_empty_q: 'Vider le panier?',
    cart_confirm_q: 'Confirmer le panier?',
    item_missing: 'L\'objet n\'existe pas?!'
};

var txt = l10n.fr
if (Y.MyWEB && l10n[Y.MyWEB.opts.lang])
    txt = l10n[Y.MyWEB.opts.lang];
    

//== Templates =========================================================

var Tpl = {};
Tpl.cart_item = 
    '<div class="sc-item" onselectstart="return false" '		+
          'sc:photo-key="{key}" '					+
          'sc:buy-vrt="{vrt}">'						+
      '<table><tr>'							+
        '<td class="sc-thumbnail" rowspan="4">'				+
          '<img src="{thumb}" alt="img"/></td>'				+
        '<td class="sc-name" colspan="3">{name}</td>'			+
        '<td class="sc-panel" rowspan="4"><table>'			+
          '<tr><td class="m-button a-inc"><span>▲</span></td></tr>'	+
          '<tr><td class="m-button a-del"><span>x</span></td></tr>'	+
          '<tr><td class="m-button a-dec"><span>▼</span></td></tr>'	+
        '</table></td>'							+
      '</tr><tr>'							+
        '<td class="sc-info" colspan="3">{info}</td>'			+
      '</tr><tr class="sc-object">'					+
        '<td class="sc-quantity">{quantity}</td>'			+
        '<td class="sc-operator">x</td>'				+
        '<td class="sc-price">{price}</td>'				+
      '</tr><tr class="sc-cost">'					+
        '<td></td>'							+
        '<td class="sc-operator">=</td>'				+
        '<td class="sc-price">{total}</td>'				+
      '</tr></table>'							+
    '</div>';


Tpl.checkout_summary = 
    '<table class="sc-checkout-summary">'				+
      '<tr class="sc-object">'						+
        '<td class="sc-description">{quantity} objet(s) en commande</td>'+
        '<td></td>'							+
        '<td class="sc-price">{basket}</td>'				+
      '</tr><tr class="sc-shipping">'					+
        '<td class="sc-description">Frais de livraison</td>'		+
        '<td class="sc-operator">+</td>'				+
        '<td class="sc-price">{shipping}</td>'				+
      '</tr><tr class="sc-cost">'					+
        '<td class="sc-description">Total</td>'				+
        '<td class="sc-operator">=</td>'				+
        '<td class="sc-price">{cost}</td>'				+
      '</tr>'								+
    '</table>';




//== Helper ============================================================

function currency(val) {
    var euro_fmt  = { decimalPlaces   : 2, 
		      decimalSeparator: '.',
		      suffix          : ' €' }
    return Y.DataType.Number.format(val, euro_fmt);
}




//== Highslide configuration ===========================================
/*
 * Add localization support
 */
function hs_localized() {
    hs.l10n = {};

    // English
    hs.lang.restoreTitleAsNext = 'Click for more next image';
    hs.lang.unknown            = 'Unknown';
    hs.lang.fromAlbum          = 'From album';
    hs.l10n.en = hs.lang;

    // French
    hs.l10n.fr = {
	cssDirection: 'ltr',
	loadingText: 'Chargement...',
	loadingTitle: 'Cliquer pour annuler',
	focusTitle: 'Cliquer pour amener au premier plan',
	fullExpandTitle: 'Afficher à la taille réelle',
	creditsText: 'Développé sur <i>Highslide JS</i>',
	creditsTitle: 'Site Web de Highslide JS',
	previousText: 'Précédente',
	nextText: 'Suivante',
	moveText: 'Déplacer',
	closeText: 'Fermer',
	closeTitle: 'Fermer (esc ou Échappement)',
	resizeTitle: 'Redimensionner',
	playText: 'Lancer',
	playTitle: 'Lancer le diaporama (barre d\'espace)',
	pauseText: 'Pause',
	pauseTitle: 'Suspendre le diaporama (barre d\'espace)',
	previousTitle: 'Précédente (flèche gauche)',
	nextTitle: 'Suivante (flèche droite)',
	moveTitle: 'Déplacer',
	fullExpandText: 'Taille réelle',
	number: 'Image %1 of %2',
	restoreTitle: 'Cliquer pour fermer l\'image, cliquer et faire glisser pour déplacer, utiliser les touches flèches droite et gauche pour suivant et précédent.',
	restoreTitleAsNext: 'Cliquer pour passer à la suivante',
	unknown: 'Inconnu',
	fromAlbum: 'Dans l\'album'
    };

    // Perform language selection
    if (Y.MyWEB && hs.l10n[Y.MyWEB.opts.lang])
	hs.lang = hs.l10n[Y.MyWEB.opts.lang];
}



/*
 * Add extra configuration for diaporama
 *  class: diaporama
 *  id   : diaporama-area
 */
function hs_configure_diaporama() {
    hs.restoreCursor     = null;
    hs.outlineType       = null;
    hs.wrapperClassName  = 'diaporama dark';
    hs.allowSizeReduction= false;
    hs.useBox            = true;
    hs.width             = 600;
    hs.height            = 400;
    hs.targetX           = 'diaporama-area 10px';
    hs.targetY           = 'diaporama-area 8px';
    hs.captionEval       = 'this.thumb.alt';
    hs.autoplay          = true;
    hs.lang.restoreTitle = hs.lang.restoreTitleAsNext;
 
    hs.addSlideshow({
	interval      : 5000,
	repeat        : true,
	useControls   : true,
	overlayOptions: { position: 'bottom right',
		          offsetY : 66               },
	thumbstrip: { position  : 'above',
		      mode      : 'horizontal',
		      relativeTo: 'expander'     }
    });
 
    hs.Expander.prototype.onImageClick = function() {
	if (/diaporama/.test(this.wrapper.className)) return hs.next();};
    hs.Expander.prototype.onBeforeClose = function() {
	if (/diaporama/.test(this.wrapper.className))  return false;   };
    hs.Expander.prototype.onDrag = function() {
	if (/diaporama/.test(this.wrapper.className))  return false;   };
    hs.Expander.prototype.onAfterGetCaption = function (sender) {
	var src  = this.a.getAttribute('src-extra');
	var orig = this.a.getAttribute('src-title');
	if (src && sender.caption) {
	    if (!orig) {
		var m    = src.match(/([^\/]*)\/?$/);
		var orig = m ? m[1].replace(/_/g, ' ') 
		             : '<i>'+hs.lang.unkown+'</i>';
	    }
	    sender.caption.innerHTML += '<div class="from-album">' + 
		hs.lang.fromAlbum + ': <a href="' + src + '">' + 
		orig + '</a></div>';
	}
    };

    // Keep the position after window resize
    hs.addEventListener(window, 'resize', function() {
	hs.getPageSize();
 
	for (var i = 0; i < hs.expanders.length; i++) {
	    var exp = hs.expanders[i];
	    if (exp) {
		var x = exp.x;
		var y = exp.y;
		// get new thumb positions
		exp.tpos = hs.getPosition(exp.el);
		x.calcThumb();
		y.calcThumb();
		// calculate new popup position
		x.pos        = x.tpos - x.cb + x.tb;
		x.scroll     = hs.page.scrollLeft;
		x.clientSize = hs.page.width;
		y.pos        = y.tpos - y.cb + y.tb;
		y.scroll     = hs.page.scrollTop;
		y.clientSize = hs.page.height;
		exp.justify(x, true);
		exp.justify(y, true);
		// set new left and top to wrapper and outline
		exp.moveTo(x.pos, y.pos);
	    }
	}
    });
}



/*
 * Add extra configuration for slidshow
 */
function hs_configure_slideshow() {
    hs.outlineType      = 'glossy-dark';
    hs.wrapperClassName = 'dark';
    hs.dimmingOpacity   = 0.75;
    hs.marginLeft       = 30;
    hs.marginRight      = 30;
    hs.marginTop        = 30;
    hs.marginBottom     = 70;

    hs.addSlideshow({
	interval      : 5000,
	repeat        : false,
	useControls   : true,
	fixedControls : 'fit',
	overlayOptions: { overlayId     : 'controlbar',
                          opacity       : .6,
		          position      : 'bottom center',
		          offsetX       : '0',
		          offsetY       : '-15',
		          hideOnMouseOut: true },
        thumbstrip    : { mode          : 'horizontal',
		          position      : 'bottom center',
		          relativeTo    : 'viewport' }
    }); 
}


/*
 * Perform configuration of highslide
 */
function hs_configure() {
    // Localiztion
    hs_localized();

    // Basic configuration
    hs.graphicsDir      = '/highslide/graphics/';
    hs.align            = 'center';
    hs.transitions      = ['expand', 'crossfade'];
    hs.fadeInOut        = true;
    hs.showCredits      = false;
    hs.captionOverlay   = { fade : false };

    // Expand open image
    hs.Expander.prototype.onDoFullExpand = function() {
	window.location.href = this.custom.url;
    }
    
    // Use image alt as title
    if (Y.one('.use-highslide-title')) {
	hs.captionEval             = 'this.thumb.alt';
	hs.captionOverlay.position = 'above';
    }

    // Configure for slideshow or diaporama
    if (Y.one('.use-highslide-diaporama')) hs_configure_diaporama();
    else	                           hs_configure_slideshow();
}



/*
 * Action to perform when document is loaded:
 *   - create additional markup 
 *   - refresh highslide
 *   - start diaporama
 */
function hs_onload() {
    // Mark thumbnail for use in highslide
    Y.all('.highslide-gallery .thumbnail').each(function(thumb) {
	var a = thumb.one('.frame a');
	if (a) a.addClass('highslide').setAttribute('rel',  'highslide');
    });

    // Force highslide reload
    hs.setClickEvents();

    // Ensure document ready is performed
    Y.on('domready', hs.ready);

    // If in diaporama launch first picture
    if (Y.one('.use-highslide-diaporama'))
	document.getElementById('diaporama-start').onclick();
}



/*
 * Start highslide
 *   load script and css, performe configuration
 */
function hs_start() {
    // Load highslide
    Y.Get.css   ('/highslide/highslide.css'); 
    Y.Get.script('/highslide/highslide-full.packed.js', {
	onSuccess: function() { hs_configure(); hs_onload(); } });
}



/*
 * Use dom markup (.use-highslide) to automatically 
 *  load and configure highslide
 */
Y.on('contentready', hs_start, '.use-highslide');




//== Thumbnail sizer ===================================================

/*
 * Add a slider allowing to do thumbnail resizing
 */
function thumbnail_sizer() {
    var sizer = Y.one('#thumbnail-sizer');

    // Sanity check
    //   - need to be an .gallery.imgbrowse
    //   - at least one thumbnail must be present
    //   - sizer required
    if (!Y.one('.gallery.imgbrowse .thumbnail') || !sizer)
	return;

    // Get stylesheet
    var sheet = Y.StyleSheet('gallery');

    // Use the first element as reference for computing 
    //  extra width added by border and padding
    var first  = Y.one('.gallery.imgbrowse .thumbnail .frame .inner img');
    var tb     = first.get('offsetHeight') - first.get('height');
    var lr     = first.get('offsetWidth' ) - first.get('width' );

    if (Y.UA.opera) {
	// XXX: offset{Width,Height} doesn't include padding
	tb += parseInt(first.getComputedStyle('paddingTop'   )) +
	      parseInt(first.getComputedStyle('paddingBottom'));
	lr += parseInt(first.getComputedStyle('paddingLeft'  )) +
	      parseInt(first.getComputedStyle('paddingRight' ));
    }

    // Get parameters for sizing
    var width  = parseInt(sizer.getAttribute('thumb:width'  ));
    var height = parseInt(sizer.getAttribute('thumb:height' ));
    var min    = parseInt(sizer.getAttribute('thumb:min'    ));
    var max    = parseInt(sizer.getAttribute('thumb:max'    ));
    var dflt   = parseInt(sizer.getAttribute('thumb:default'));
	
    // Construct widget skeleton
    var YNc    = Y.Node.create;
    var small  = YNc('<img class="m-button" title="Smaller" ' +
		     ' src="/images/common/misc/thumbnail-small.png"/>');
    var large  = YNc('<img class="m-button" title="Larger"' +
		     ' src="/images/common/misc/thumbnail-large.png"/>');
    var slider = YNc('<div/>');
    var widget = YNc('<table/>').append(
		 (YNc('<tr/>').append(YNc('<td/>').append(small))
		              .append(YNc('<td/>').append(slider))
		              .append(YNc('<td/>').append(large))))
	         .setStyle('verticalAlign', 'middle');

    // Append widget to document and render slider
    sizer.append(widget);
    var slider = new Y.Slider({ 
	    thumbImage : '/images/common/misc/thumbX.png',
	    contentBox : slider,
	    min        : min,
	    max        : max,
	    value      : dflt,
	    railSize   : '150px' 
	}).render();

    // I18N / L10N
    if (Y.MyWEB && Y.MyWEB.opts.lang) {
	switch(Y.MyWEB.opts.lang) {
	case 'fr':
	    small.setAttribute('title', 'Plus petit');
	    large.setAttribute('title', 'Plus large');
	}
    }
	
    // StyleSheet (rules used for thumbnail resizing)
    var imgRule   = '.gallery.imgbrowse .thumbnail .frame .inner img';
    var frameRule = '.gallery.imgbrowse .thumbnail .frame .inner';
    
    // Buttons for increase/decrease
    small.on('click', function() {
	    slider.set('value', Math.max(slider.get('min'), 
					 slider.get('value') - 10)); }); 
    large.on('click', function() {
	    slider.set('value', Math.min(slider.get('max'), 
					 slider.get('value') + 10)); }); 
    // Slider action (on value)
    slider.on('valueChange', function(evt) { 
	// XXX: Re-layout problem for webkit (safari/chrome) when increasing
	//       (resizing at n+1 and n is not enough)
	var pct      = evt.newVal;
	var n_width  = Math.floor(width  * pct / 100);
	var n_height = Math.floor(height * pct / 100);
	sheet.set(frameRule, { width    : (n_width  + lr) + 'px',
		               height   : (n_height + tb) + 'px'  });
	sheet.set(imgRule,   { maxWidth : n_width         + 'px',
		               maxHeight: n_height        + 'px'  });
	// Update cookie
	Y.Cookie.set('thumbnail-sizer', pct, 
		     Y.merge(Y.MyWEB.opts.cookie, { path: '/' }));
      });
    
    // Update thumbnail size
    //   According to cookie or default value
    //   (Ideally thumbnail size should be performed before dom ready)
    var val = parseInt(Y.Cookie.get('thumbnail-sizer'));
    slider.set('value', val ? val : dflt);
}



/*
 * Use dom markup to automatically add slider
 *   (need to be performed as soon, to avoid initiale resizing)
 */
// require '#thumbnail-sizer' AND '.gallery.imgbrowse .thumbnail'
Y.on('contentready', function() {
	Y.on('contentready', thumbnail_sizer, '.gallery.imgbrowse .thumbnail');
    }, '#thumbnail-sizer');




//== Gallery Store =====================================================

/*
 * Store for keeping track of items and their variants
 */
function GalleryStore() {
    this.store  = {};
    GalleryStore.superclass.constructor.apply(this, arguments); 
}


Y.extend(GalleryStore, Y.Base, { 
    remove: function(key, vrt, opt) {
	var root = this.store[key];
	if ((root == null) || (root.vrt[vrt] == null)) return;
	var data = root.vrt[vrt];
	data.qty -= 1;
	if (data.qty < 0) data.qty = 0;
	if (opt.img) data.img = opt.img;
	else         opt.img  = data.img;
	this.fire('update', key, vrt, data.qty, opt); 
    },
    add: function(key, vrt, opt) {
        var root = this.store[key];
	if (root == null) root = this.store[key] = { vrt: {} };
	var data  = root.vrt[vrt];
	if (data == null) data = root.vrt[vrt] = { qty : 0 };
	data.qty += 1;
	if (opt.img) data.img = opt.img;
	else         opt.img  = data.img;
	this.fire('update', key, vrt, data.qty, opt);
    },
    trash: function(key, vrt, opt) {
        var root = this.store[key];
	var cnt  = 0;
	if (root == null) return;
	if (vrt  != null) { delete root.vrt[vrt]; for (e in root.vrt) cnt++; }
	if (! cnt) delete this.store[key];
	this.fire('delete', key, vrt, cnt, opt);
    },
    empty: function(opt) {
        this.store  = {};
	this.fire('clear', opt);
    },
    get: function(key, vrt) {
	var root = this.store[key];
	return root == null ? null : root.vrt[vrt];
    },
    each: function(fn, context) {
	for (key in this.store) {
	    var root = this.store[key];
	    for (vrt in root.vrt)
		fn.apply(context, [key, vrt, root.vrt[vrt].qty]);
	}
    },
    getCount : function() {
	var count = 0;
	this.each(function(key, vrt, qty) { count += 1; });
	return count;
    },
    save  : function() {
    },
    load  : function() {
    }
}); 



/*
 * Store (instanciated GalleryStore)
 */
var store = new GalleryStore();




//----------------------------------------------------------------------
// on Load
//----------------------------------------------------------------------

Y.on('load', function() {

//== Gallery ===========================================================

/*
 * Turn whole thumbnail into a link
 *   Except if using a slideshow galery (currently: highslide)
 */
if (!Y.one('.use-highslide')) {
    // Make cursor a pointer on whole thumbnail
    var sheet = Y.StyleSheet('gallery');
    sheet.set('.gallery .thumbnail', { cursor: 'pointer' });

    // Delegate thumbnail click to each gallery
    /* XXX: Strange delegate behaviour on webkit
    Y.all('.gallery').each(function(gallery) { 
        gallery.delegate('click',  function(evt) { 
  	    var tgt = evt.target.closest('.thumbnail');
	    var a   = tgt.one('.frame a');
	    if (a) window.location.href = a.getAttribute('href');
          }, '.thumbnail');
    });
    */
    Y.all('.gallery .thumbnail').each(function(thumb) { 
        thumb.on('click',  function(evt) { 
	    var a   = thumb.one('.frame a');
	    if (a) window.location.href = a.getAttribute('href');
	});
    });
}



/*
 * Information about thumbnail
 */
Y.all('.gallery .thumbnail').each(function(thumb) {
    var info  = thumb.one('> .thumb-info'    );
    var btn   = thumb.all('> .thumb-info-btn');
    var later = null;

    if (!info || !btn.size()) return;
    info.plug(Y.Plugin.EasyNode);
    
    btn.on('mouseenter', function() { 
	if (later) later.cancel();
	if (!info.ez.isVisible())
	    later = Y.later(300, info.ez, info.ez.fadeIn);      	});
    btn.on('mouseleave', function() {
	if (later) later.cancel();
	if (info.ez.isVisible())
	    info.ez.fadeOut();      					});
});



/*
 * Panel selection for thumbnail
 */
if (Y.one('.gallery .thumbnail .thumb-add-btn')) {
    // Show/Hide panel
    Y.all('.gallery .thumbnail').each(function(thumb) {
	var pnl   = thumb.one('> .thumb-add-panel');
	var btn   = thumb.all('> .thumb-add-btn'  );
	var later = null;

	if (!pnl || !btn.size()) return;
	pnl.plug(Y.Plugin.EasyNode);

	btn.on('mouseenter', function() { 
	    if (later) later.cancel();
	    if (!pnl.ez.isVisible()) 
		later = Y.later(800, pnl.ez, pnl.ez.fadeIn);		});
	btn.on('mouseleave', function(evt) {
	    if (later) later.cancel();
	    if (pnl.ez.isVisible() && (pnl != evt.relatedTarget))
		pnl.ez.fadeOut();        				});
	pnl.on('mouseleave', function(evt) {
	    if (later) later.cancel();
	    if (pnl.ez.isVisible() && btn.indexOf(evt.relatedTarget) < 0)
		pnl.ez.fadeOut();        				});
    });

    // Item selection
    Y.all('.gallery').each(function(gallery) { 
	// Action in panel
	gallery.delegate('click',  function(evt) { 
	    var action   = evt.target;
	    var thumb    = evt.target.closest('.thumbnail');
	    var item     = evt.target.closest('.thumb-add-item');
	    var key      = thumb.getAttribute('thumb:key');
	    var vrt      = item.getAttribute('thumb:vrt');
	    var opt      = { src: thumb,
			     img: thumb.one('.inner img').getAttribute('src')};
	    if (action.test('.a-inc')) { store.add   (key, vrt, opt); }
	    if (action.test('.a-dec')) { store.remove(key, vrt, opt); }
          }, '.thumbnail .thumb-add-panel .m-button');

	// Toggled selected button
	gallery.delegate('click',  function(evt) { 
	    var thumb    = evt.target.closest('.thumbnail');
	    var key      = thumb.getAttribute('thumb:key');
	    var opt      = { src: thumb };
	    store.trash(key, null, opt); 
	  }, '.thumbnail .thumb-selected-btn');

	// Adding item
	gallery.delegate('click',  function(evt) { 
	    var thumb    = evt.target.closest('.thumbnail');
	    var pnl      = thumb.one('> .thumb-add-panel');
	    var key      = thumb.getAttribute('thumb:key');
	    var opt      = { src: thumb, 
			     img: thumb.one('.inner img').getAttribute('src')};
	    var vrt      = 'dft';

	    if (pnl) {
		var      val = Y.one('.sc-default');
		if (val) val = val.one('input[type=radio]:checked');
		if (val) val = val.get('value');
		if (val) { // Retrieve matching default choice
		    var dfts = val.split(/,/);
		    pnl.all('.thumb-add-item').each(function(item) {
			var v = item.getAttribute('thumb:vrt');
			if (Y.Array.indexOf(dfts, v) >= 0) {
			    vrt = v; return false;
			}
		    });
		} else {   // Take the first one defined in panel
		    vrt = pnl.one('.thumb-add-item').getAttribute('thumb:vrt');
		}
	    }
	    store.add(key, vrt, opt);	
	  }, '.thumbnail .thumb-add-btn');
    });


    // Mark thumbnail as selected
    store.on('clear',  function(evt, opt) {
	Y.all('.gallery .thumbnail .thumb-selected-btn')
	    .removeClass('thumb-selected');
      });
    store.on('delete',  function(evt, key, vrt, cnt, opt) {
	if (cnt > 0) return;
	Y.all('.gallery .thumbnail[thumb\\:key="'+ key +
	      '"] .thumb-selected-btn').removeClass('thumb-selected');
      });
    store.on('update', function(evt, key, vrt, qty, opt) {
	Y.all('.gallery .thumbnail[thumb\\:key="'+ key +
	      '"] .thumb-selected-btn').addClass('thumb-selected');
      });

    // Update item panel content
    store.on('clear',  function(evt, opt) {
	Y.all('.gallery .thumbnail .thumb-add-quantity')
	    .setContent('0');
      });
    store.on('delete',  function(evt, key, vrt, cnt, opt) {
	Y.all('.gallery .thumbnail[thumb\\:key="'+ key +'"]'        +
	      ((vrt != null) ? ' [thumb\\:vrt="' + vrt + '"]' : '') +
	      ' .thumb-add-quantity').setContent('0');
      });
    store.on('update', function(evt, key, vrt, qty, opt) {
	Y.all('.gallery .thumbnail[thumb\\:key="'+ key +'"] [thumb\\:vrt="' +
	      vrt + '"] .thumb-add-quantity').setContent(qty.toString());
      });
}



/*
 * Cart / Checkout
 */
if (Y.one('.sc-cart')) {
    var cart        = Y.one('.sc-cart'       ).plug(Y.Plugin.EasyNode);
    var cart_helper = Y.one('.sc-cart-helper').plug(Y.Plugin.EasyNode);

    /* Enhance store
     */
    store.getTotal = function() {
        var total = 0;
	this.each(function(key, vrt, qty) { 
	    var variant = null;
	    for (var i = 0 ; i < sc_data.variant.length ; i++)
		if ((variant = sc_data.variant[i]).key == vrt)
		    break;
	    total += variant.price * qty;
	});
	return total;
    };

    store.getShipping = function() {
	return sc_data.shipping;
    };

    store.order = function() {
	var seller = sc_data.seller;
	var winpar = 'width=950,height=600' + 
	             ',scrollbars,location=0,resizable,status=0';
	var params        = {
	    cmd		  : '_cart',
	    invoice	  : Y.DataType.Date.format(new Date, 'Y.m.d-H:i:s'),
	    upload	  : 1,
	    business	  : seller.id,
	    currency_code : 'EUR',
	    lc		  : 'FR',
	    handling_cart : this.getShipping() };
	if (seller.origin)
	    params.custom           = seller.origin;
	if (seller.banner)
	    params.cpp_header_image = seller.banner;
	if (seller.notify)
	    params.notify_url       = seller.notify;
	if (seller['return'])
	    params['return']        = seller['return'];
	if (seller.custom)
	    params.custom           = seller.custom;

	var counter       = 1;
	this.each(function(key, vrt, qty) {
	    if (qty <= 0) return true;

	    var variant = null;
	    for (var i = 0 ; i < sc_data.variant.length ; i++)
		if ((variant = sc_data.variant[i]).key == vrt)
		    break;
	    params['item_name_'   + counter] = 
		' No' + key + ' (' + variant.title + ')';
	  //params['item_number_' + counter] = rec.get('reference') + '/' +
	  //	rec.get('support') + '/' + rec.get('format');
	    params['quantity_'    + counter] = qty;
	    params['amount_'      + counter] = variant.price;
	    counter  += 1;
        });

	var data = [];
        for (var key in params) {
	    var val   = params[key];
	    var e_key = encodeURIComponent(key);
	    var e_val = encodeURIComponent(val);
	    if (val == null)    data.push(e_key);
	    else                data.push(e_key + '=' + e_val);
	}
	data = data.join('&');
	window.open ("https://www.paypal.com/cgi-bin/webscr?" + data,
		     "paypal", winpar);
    };


    /* Checkout
     */
    // Insert checkout summary
    Y.all('.sc-checkout').each(function(checkout) {
	checkout.setAttribute('disabled', 'disabled' );
	checkout.append(Y.substitute(Tpl.checkout_summary, {
		    basket  : currency(0), 
		    shipping: currency(0), 
		    cost    : currency(0), 
		    quantity: 0 }));
    });

    // Action on checkout: emtpy
    Y.all('.sc-checkout-empty').on('click', function() {
	if (! store.getCount()) return;
	if (! confirm(txt.cart_empty_q)) return;
	store.empty();
	store.save();
    });

    // Action on checkout: Confirm
    Y.all('.sc-checkout-validate').on('click', function() {
        if (! store.getCount()) return;
	if (! confirm(txt.cart_confirm_q)) return;
	store.save();
	store.order();
    });

    // Update checkout content
    var updateCheckout = function() {
	var basket   = store.getTotal();
	var shipping = basket ? store.getShipping() : 0;
	var cost     = basket + shipping;
	var quantity = store.getCount();
	Y.all('.sc-checkout').each(function(checkout) {
	    var node = Y.Node.create(Y.substitute(Tpl.checkout_summary, {
		    basket  : currency(basket),
		    shipping: currency(shipping),
		    cost    : currency(cost),
		    quantity: quantity }));
	    if (quantity > 0) checkout.removeAttribute('disabled');
	    else              checkout.setAttribute('disabled', 'disabled' );
	    checkout.children().remove();
	    checkout.append(node);
	    });
    };
    store.on('update', updateCheckout);
    store.on('delete', updateCheckout);
    store.on('clear',  updateCheckout);


    /* Cart
     */
    /*
    Y.all('.thumbnail').plug(Y.Plugin.EasyNode);
    store.on('update', function(evt, key, vrt, qty, opts) {
	    if (opts && opts.src && opts.src.test('.thumbnail'))
		opts.src.ez.transfert({dst: cart});
	});
    */

    // Action on cart item: add/remove/trash
    cart.delegate('click', function(evt) {
	var action = evt.target.closest('.m-button');
	var citem  = evt.target.closest('.sc-item');
	if (!action) return;
	var opts    = { src: citem };
	var key     = citem.getAttribute('sc:photo-key');
	var vrt     = citem.getAttribute('sc:buy-vrt');
	
	try {
	    if (action.hasClass('a-inc')) store.add   (key, vrt, opts);
	    if (action.hasClass('a-dec')) store.remove(key, vrt, opts);
	    if (action.hasClass('a-del')) store.trash (key, vrt, opts);
	} catch(e) {
	    throw e;
	}
      }, '.sc-item' );

    // Update cart content
    store.on('update', function(evt, key, vrt, qty, opts) {
	// Find information about requested item variant
	var variant = null;
	for (var i = 0 ; i < sc_data.variant.length ; i++)
	    if ((variant = sc_data.variant[i]).key == vrt)
		break;
	if (!variant) {
	    alert(Y.substitute('Variant {vrt} not found for item {item}', {
			vrt: vrt, item: key }));
	    return;
	}
    
	// Create corresponding node from template
	var name = key;
	if (Y.DataType.Number.parse(key) !== null) name = 'N°' + key;
	if (opts && opts.name                    ) name = opts.name;
	var node = Y.Node.create(Y.substitute(Tpl.cart_item, {
		key     : key,
		vrt     : vrt,
		info    : '(' + variant.title + ')',
		name    : name,
		quantity: qty,
		price   : currency(variant.price      ),
		total   : currency(variant.price * qty),
		thumb   : (opts && opts.img) ? opts.img : '/foo/bar.png'
	    })).plug(Y.Plugin.EasyNode);

	// Hide cart helper
	if (cart_helper.ez.isVisible())
	    cart_helper.ez.hide();

	// Find corresponding cart item
	var citem   = cart.one('[sc\\:photo-key="'  + key + '"]'+
			       '[sc\\:buy-vrt="'    + vrt + '"]');

	// Update cart ...
	if (citem) {  // ... by replacing previous item
	    citem.replace(Y.Node.getDOMNode(node));
	} else {      // ... by inserting item into cart
	    // Try to smartly insert by grouping same key
	    var where = cart.all('[sc\\:photo-key="' + key + '"]').last();
	    if (where) where.insert(node, 'after');
	    else       cart.append(node);
	}
	citem = node;
	
	// Scroll item into view in cart
	citem.scrollIntoView(cart);
	
	// Make animation
	if (opts && opts.src) {
	    //if (opts.src.test('.sc-item')) src.ez.transfert({dst: cart});
	} 

    });

    store.on('delete' , function(evt, key, vrt, cnt, opts) {
	// Item has been deleted
	//   if no variant (vrt), it's all of them
	var selector       = '[sc\\:photo-key="' + key + '"]';
	if (vrt) selector += '[sc\\:buy-vrt="'   + vrt + '"]';
	var all   = cart.all(selector);
	var count = all.size();
	all.each(function(node) {
	    node.ez.collapse({ 
		callback: function() {
			node.remove();
			if (--count == 0 && 
			    !Y.one('.sc-item') && !cart_helper.ez.isVisible())
			    cart_helper.ez.fadeIn(); }
		});
	});
    });

    store.on('clear', function() {
	var all   = cart.all('.sc-item');
	var count = all.size();
	all.each(function(node) {
	    node.ez.collapse({ 
		callback: function() { 
			node.remove(); 
			if (--count == 0) cart_helper.ez.fadeIn(); } 
	        });
	});
	
    });
}

});

});

