// $Id: yui-custom.js 1210 2009-11-01 16:23:36Z sdalu $


/*

Ext.Fx.transfert = function(to, o) {
    var from = this;
    var to   = Ext.get(to);
    var el   = Ext.get(this.dom);

    o = Ext.applyIf(o || {},
                    { duration: .2, easing: 'easeIn' });

    el.queueFx(o, function(){
        from.show();
	to.show();
	
	var f_b    = from.getBox();
	var t_b    = to.getBox();
	var proxy  = Ext.get(document.body ||
			     document.documentElement).createChild({
				     style : {
					 visbility: 'hidden',
					 position : 'absolute',
					 "z-index": 300, // yee haw
					 border   : '3px solid grey'
				     }
				 });
	var scale  = Ext.isBorderBox ? 0 : 1;
	var width  = proxy.getFrameWidth('lr') * scale;
	var height = proxy.getFrameWidth('tb') * scale;

	proxy.animate({
	    top    : { from : f_b.y,             to : t_b.y             },
	    left   : { from : f_b.x,             to : t_b.x             },
	    height : { from : f_b.height-height, to : t_b.height-height },
	    width  : { from : f_b.width-width,   to : t_b.width-width   } }, 
	    o.duration, 
	    function() { proxy.remove(); el.afterFx(o); },
	    o.easing);
    });
    
    return this;
};
*/

//== node-extra ========================================================

YUI.add('node-extra', function(Y) {

Y.Node.prototype.closest = function(fn) {
    if (typeof fn === 'string') {
	if (this.test(fn)) return this;
    } else {
	if (fn(this)     ) return this;
    }
    return this.ancestor(fn);
};

Y.Node.prototype.parent = function(selector) {
    return this.ancestor(selector);
};

Y.Node.prototype.children = function(selector) {
    return selector ? this.get('children').filter(selector)
                    : this.get('children');
};

Y.Node.prototype.siblings   = function(selector) {
    var _next = [], _prev = [], s;    
    s = this;
    while (s = s.get('nextSibling'))
        if ((s.get('nodeType') == 1) && 
	    (!selector || s.test(selector))) _next.push(s);
    s = this;
    while (s = s.get('previousSibling'))
        if ((s.get('nodeType') == 1) &&
	    (!selector || s.test(selector))) _prev.unshift(s);
    return Y.all(_prev.concat(_next));
};

Y.Node.prototype.radioClass = function(c) {
    this.addClass(c);
    this.siblings().removeClass(c);
    return this;
};

Y.Node.prototype.appendTo = function(e) {
    Y.one(e).append(this);
    return this;
};


Y.Node.prototype.scrollIntoView = function(container, hscroll) {
    // Fallback to standard behaviour if no or wrong argument
    if (!container || !Y.one(container)) {
	this._node.scrollIntoView();
	return this;
    }

    var c = Y.one(container);


    var oc = c.getXY();
    var ot = this.getXY();
    var o = [ot[0]-oc[0],ot[1]-oc[1]];



    var l = o[0] + c.get('scrollLeft');
    var t = o[1] + c.get('scrollTop');
    var b = t + this.get('offsetHeight');
    var r = l + this.get('offsetWidth');



    var ch = c.get('clientHeight');
    var ct = c.get('scrollTop');
    var cl = c.get('scrollLeft');
    var cb = ct + ch;
    var cr = cl + c.get('clientWidth');

    if (this.get('offsetHeight') > ch || t < ct) {
	c.set('scrollTop', t);
    } else if (b > cb){
	c.set('scrollTop', b-ch);
    }
    //c.set('scrollTop', c.get('scrollTop')); // corrects IE, other browsers will ignore

    if(hscroll !== false){
	if(this.get('offsetWidth') > c.get('clientWidth') || l < cl){
	    c.set('scrollLeft', l);
	}else if(r > cr){
	    c.set('scrollLeft', r - c.get('clientWidth'));
	}
	//c.set('scrollLeft',  c.get('scrollLeft'));
    }
    return this;
};





Y.NodeList.prototype.first = function() {
    return this.item(0);
};

Y.NodeList.prototype.last = function() {
    return this.item(this.size()-1);
};


}, '0.1.0', {requires: [ 'node-base' ]});


//== task ==============================================================


YUI.add('task', function(Y) {

var L = Y.Lang;

Y.task = function(fn, data, scope) {
    scope = scope || {};
    gdata = Y.Array(data);

    return {
	id    : null,
	cancel: function() {
	    if (this.id != null) {
		clearTimeout(this.id);
		this.id = null
	    } },
	delay : function(msec, data) {
	    this.cancel();
	    var task = function() {
		fn.apply(scope, L.isUndefined(data) ? gdata : Y.Array(data));
		this.id = null;
	    };
	    if (msec > 0)
		this.id = setTimeout(task, msec);
	    else if (msec == 0)
		task();  	                                        },
	now   : function(data) {
	    this.delay(0, data);                  	                }
    };
};



Y.repeat = function(fn, data) {
    var d  = Y.Array(data);
    var c  = 0;
	
    return {
        id    : null,
	count : function() { 
	    return c; },
	cancel: function() {
	    if (this.id != null) {
		clearInterval(this.id);
		this.id = null
	    } },
	start : function(msec, count, data) {
	    var me = this;
	    this.cancel();
	    this.id = setInterval(function() {
		if (c++ > count) {
		    this.cancel();
		} else {
		    if (L.isUndefined(data)) data = d;
		    fn.apply(me, Y.Array(data));
	        } }, msec); }
    }
}

}, '0.1.0' ,{requires:['yui-base']});





//== mask ==============================================================


YUI.add('mask', function(Y) {

function Mask(config) { 
    Mask.superclass.constructor.apply(this, arguments); 
    this.config = Y.merge({ node: Y.one(document.body) }, config);
    this._node  = this.config.node;
    this._mask  = Y.Node.create('<div/>');
    this._mask.set('id', Y.guid());
    this.config.node.append(this._mask);
} 

Y.extend(Mask, Y.Base, { 
    show   : function() {
	this._mask.addClass('m-mask');
	this._node.addClass('m-masked');
    },
    hide   : function() {
	this._mask.removeClass('m-mask');
	this._node.removeClass('m-masked');	
	// XXX: webkit bug: overflow vs scrollbar
	if (Y.UA.webkit) {
	    var top = this._node.get('scrollTop');
	    this._node.set('scrollTop', top < 1 ? 1 : (top - 1));
	    this._node.set('scrollTop', top);       
	}
    }
}); 

Y.Mask = Mask;

}, '0.1.0', { requires: [ 'node' ] });




//== easy node =========================================================



YUI.add('easy-node', function(Y) {

function EasyNodePlugin(config) {
    this._node = config.host;
}

EasyNodePlugin.NS        = "ez";
EasyNodePlugin.prototype = {
    show      : function() { this._node.setStyle('display', 'block'); 
                             return this._node; },
    hide      : function() { this._node.setStyle('display', 'none' ); 
                             return this._node; },
    isVisible : function() { return this._node.getStyle('display')!='none' },

    center    : function() { 
	var n = this._node;
	var x = (n.get('winWidth' )-n.get('offsetWidth' )) / 2;
	var y = (n.get('winHeight')-n.get('offsetHeight')) / 2;
	n.setXY([x, y]); 
	return this._node; },

    fade : function(opt) {
	opt = Y.merge({ duration : 0.3, easing   : Y.Easing.easeIn,
			from     : 0,	to       : 1 	 }, opt || {});

        var anim    = new Y.Anim({ node      : this._node,
				   from      : { opacity : opt.from },
				   to        : { opacity : opt.to },
				   easing    : opt.easing,
				   duration  : opt.duration });
	anim.on('start', function() { 
	    var direction = this.get('reverse') ? 'to' : 'from';
	    var opacity   = this.get(direction).opacity;
	    var node    =   this.get('node');
	    if (opacity != null)
		node.setStyle('opacity', opacity);
	    node.setStyle('display', 'block'); 
        });
	anim.after('end', function() {
	    var node    = this.get('node');
	    var opacity = node.getStyle('opacity');
	    if (opacity == 1) { node.setStyle('opacity', null);   } 
	    if (opacity == 0) { node.setStyle('display', 'none'); }
	});
	if (opt.callback)
	    anim.after('end', opt.callback);
	anim.run(); 
	return this._node; },

    fadeIn : function(opt) {
	opt = Y.merge({ from: 0, to: 1 }, opt || {});
	return this.fade(opt); },

    fadeOut : function(opt) {
	opt = Y.merge({ from: 1, to: 0 }, opt || {});
	return this.fade(opt); },

    collapse : function(opt) {
	opt = Y.merge({ duration : 0.3, easing   : Y.Easing.easeIn,
			from     : 0,	to       : 1 	 }, opt || {});
        var anim    = new Y.Anim({ node      : this._node,
				   to        : { height : 0 },
				   easing    : opt.easing,
				   duration  : opt.duration });
	anim.on('start', function() { 
		this._node.setStyle('overflow', 'hidden');
	    });
	if (opt.callback)
	    anim.after('end', opt.callback);
	anim.run(); 
	return this._node; },

    transfert : function(opt) {
	if (opt.dst == null) return;

	opt = Y.merge({ duration : 0.3, easing   : Y.Easing.easeIn },
		      opt || {});

	var s      = this._node;
	var d      = opt.dst;
	var scale  = 1;
	var proxy  = Y.Node.create('<div class="m-proxy"/>')
	              .setStyles({ position : 'absolute',
				   zIndex   : 16000, // yee haw
				   border   : '3px solid grey' });
        var anim   = new Y.Anim({ 
		node      : proxy,
		from      : { top   : s.getY(),
			      left  : s.getX(),
			      width : s.get('offsetWidth'),
			      height: s.get('offsetHeight') },
		to        : { top   : d.getY(),
			      left  : d.getX(),
			      width : d.get('offsetWidth'),
			      height: d.get('offsetHeight')  },
		easing    : opt.easing,
		duration  : opt.duration });

	anim.after('start', function() { Y.one('body').append(proxy); });
	anim.on   ('end',   function() { proxy.remove();              });

	anim.run();
	return this;
    },

    frame      : function(opt) {
	opt = Y.merge({ color    : '#C3DAF9',
			duration : 0.5, easing   : Y.Easing.easeIn },
		      opt || {});
	var scale   = 1;
	var xy      = this._node.getXY();
	var width   = this._node.get('offsetWidth');
	var height  = this._node.get('offsetHeight');
	var proxy   = Y.Node.create('<div class="m-proxy"/>')
	                    .setStyles({ display  : 'none', 
					 position : 'absolute', 
					 zIndex   : 16000, 
					 border   : '0px solid '+opt.color });
	var anim    = new Y.Anim({
		node      : proxy,
		from      : { opacity    : 1,
			      top        : xy[1],
			      left       : xy[0],
			      borderWidth: 0,
			      height     : height,
			      width      : width          },
		to        : { opacity    : 0,
			      top        : xy[1] - 20,
			      left       : xy[0] - 20,
			      borderWidth: 10,
			      height     : height + 20 * scale,
			      width      : width  + 20 * scale   },
		iterations: 1,
		easing    : opt.easing,
		duration  : opt.duration });
	
	anim.after('start', function() { proxy.setStyle('display','block'); });
	anim.on   ('end',   function() { proxy.remove(); }); 
	Y.one(document.body).append(proxy);
	anim.run(); 
	return this._node; }
};


Y.namespace('Plugin');
Y.Plugin.EasyNode = EasyNodePlugin;


}, '0.1', { requires: [ 'node-base', 'node-style', 'node-screen',
			'anim-base', 'anim-easing' ] });
