Ext.QuickTips.init();

largeImage = function(path) {
	if (!Ext.getCmp('imagewindow')) {
		var image = new Image();
		image.onload = function(i) {
			new Ext.Window({ id: 'imagewindow', closeAction: 'close', initHidden: false, 
				width: this.width + 14,
				items: { xtype: 'box', contentEl: this },
				listeners: {
					'afterlayout' : function(cmp) { 
						cmp.center(); 
						cmp.setPagePosition(cmp.getPosition()[0],10); 
					}
				}
			});
		}
		image.src = path;
	}
	return false;
}

playVideo = function(vid,site) {
	var google_tpl = new Ext.XTemplate(
		'<embed class="videoplayer" type="application/x-shockwave-flash" src="http://video.google.com/googleplayer.swf?docId={vid}&hl=en"></embed>'
		);
		
	var youtube_tpl = new Ext.XTemplate(
		'<object class="videoplayer">',
		'<param name="movie" value="http://www.youtube.com/v/{vid}&hl=en&fs=1&rel=0"></param>',
		'<param name="allowFullScreen" value="true"></param>',
		'<param name="allowscriptaccess" value="always"></param>',
		'<embed class="videoplayer" src="http://www.youtube.com/v/{vid}&hl=en&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true">',
		'</embed>',
		'</object>'
		);

	var tpl = (site == 'Google') ? google_tpl : youtube_tpl;
	if (!Ext.getCmp('videocontainer')) {
		var container = new Ext.Container({ id: 'videocontainer', renderTo: 'videospot', hidden: true,
			items: [
			{ xtype: 'box', html: tpl.apply({ vid: vid  }) },
			{ xtype: 'box', html: '<a href="#" class="close" onclick="return closeVideo();" rel="nofollow">Close Video</a>'}
			]
		});
		container.show();
		container.getEl().show(true);
	}
	return false;
}

closeVideo = function(vid,site) {
	Ext.getCmp('videocontainer').destroy();
	return false;
}

Ext.InfoBubble = Ext.extend(Ext.Tip, {
    /**
     * @cfg {Mixed} target The target HTMLElement, Ext.Element or id to associate with this tooltip.
     */
    /**
     * @cfg {Boolean} autoHide True to automatically hide the tooltip after the mouse exits the target element
     * or after the {@link #dismissDelay} has expired if set (defaults to true).  If {@link closable} = true a close
     * tool button will be rendered into the tooltip header.
     */
    /**
     * @cfg {Number} showDelay Delay in milliseconds before the tooltip displays after the mouse enters the
     * target element (defaults to 500)
     */
    showDelay: 500,
    /**
     * @cfg {Number} hideDelay Delay in milliseconds after the mouse exits the target element but before the
     * tooltip actually hides (defaults to 200).  Set to 0 for the tooltip to hide immediately.
     */
    hideDelay: 200,
    /**
     * @cfg {Number} dismissDelay Delay in milliseconds before the tooltip automatically hides (defaults to 5000).
     * To disable automatic hiding, set dismissDelay = 0.
     */
    dismissDelay: 5000,
    /**
     * @cfg {Array} mouseOffset An XY offset from the mouse position where the tooltip should be shown (defaults to [15,18]).
     */
    mouseOffset: [15,18],
    /**
     * @cfg {Boolean} trackMouse True to have the tooltip follow the mouse as it moves over the target element (defaults to false).
     */
    trackMouse : false,
    constrainPosition: true,

    // private
    initComponent: function(){
        Ext.InfoBubble.superclass.initComponent.call(this);
        this.lastActive = new Date();
        this.initTarget();
		this.on('render', this.initBubble, this );
    },

    // private
    initTarget : function(){
        if(this.target){
            this.target = Ext.get(this.target);
            this.target.on('mouseover', this.onTargetOver, this);
            this.target.on('mouseout', this.onTargetOut, this);
            this.target.on('mousemove', this.onMouseMove, this);
        }
    },

	initBubble : function() {
		this.el.on('mouseout', this.onTargetOut, this);
	},
	
    // private
    onMouseMove : function(e){
        this.targetXY = e.getXY();
        if(!this.hidden && this.trackMouse){ this.setPagePosition(this.getTargetXY()); }
    },

    // private
    getTargetXY : function(){
        return [this.targetXY[0]+this.mouseOffset[0], this.targetXY[1]+this.mouseOffset[1]];
    },

    // private
    onTargetOver : function(e){
        if(this.disabled || e.within(this.target.dom, true) || (this.el && e.within(this.el.dom, true)) ){ return; }
        this.clearTimer('hide');
        this.targetXY = e.getXY();
        this.delayShow();
    },

    // private
    delayShow : function(){
        if(this.hidden && !this.showTimer){
            if(this.lastActive.getElapsed() < this.quickShowInterval){ this.show();
            } else{ this.showTimer = this.show.defer(this.showDelay, this);
            }
        } else if(!this.hidden && this.autoHide !== false){ this.show(); }
    },

    // private
    onTargetOut : function(e){
		// check for a mouse move from target into the rollover
		if ( this.el && e.within(this.el.dom, true) ) {
			this.clearTimer('hide');
			return;
		}
        if(this.disabled || e.within(this.target.dom, true) ){ return; }
        this.clearTimer('show');
        if(this.autoHide !== false){ this.delayHide(); }
    },

    // private
    delayHide : function(){
        if(!this.hidden && !this.hideTimer){ this.hideTimer = this.hide.defer(this.hideDelay, this); }
    },

    /**
     * Hides this tooltip if visible.
     */
    hide: function(){
        this.clearTimer('dismiss');
        this.lastActive = new Date();
        Ext.InfoBubble.superclass.hide.call(this);
    },

    /**
     * Shows this tooltip at the current event target XY position.
     */
    show : function(){
        this.showAt(this.getTargetXY());
    },

    // inherit docs
    showAt : function(xy){
        this.lastActive = new Date();
        this.clearTimers();
        Ext.InfoBubble.superclass.showAt.call(this, xy);
        if(this.dismissDelay && this.autoHide !== false){
            this.dismissTimer = this.hide.defer(this.dismissDelay, this);
        }
    },

    // private
    clearTimer : function(name){
        name = name + 'Timer';
        clearTimeout(this[name]);
        delete this[name];
    },

    // private
    clearTimers : function(){
        this.clearTimer('show');
        this.clearTimer('dismiss');
        this.clearTimer('hide');
    },

    // private
    onShow : function(){
        Ext.InfoBubble.superclass.onShow.call(this);
        Ext.getDoc().on('mousedown', this.onDocMouseDown, this);
    },

    // private
    onHide : function(){
        Ext.InfoBubble.superclass.onHide.call(this);
        Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
    },

    // private
    onDocMouseDown : function(e){
        if(this.autoHide !== false && !e.within(this.el.dom)){
            this.disable();
            this.enable.defer(100, this);
        }
    },

    // private
    onDisable : function(){
        this.clearTimers();
        this.hide();
    },

    // private
    adjustPosition : function(x, y){
        // keep the position from being under the mouse
        var ay = this.targetXY[1], h = this.getSize().height;
        if(this.constrainPosition && y <= ay && (y+h) >= ay){
            y = ay-h-5;
        }
        return {x : x, y: y};
    },

    // private
    onDestroy : function(){
        Ext.InfoBubble.superclass.onDestroy.call(this);
        if(this.target){
            this.target.un('mouseover', this.onTargetOver, this);
            this.target.un('mouseout', this.onTargetOut, this);
            this.target.un('mousemove', this.onMouseMove, this);
        }
    }
});


/* print dialog functions */

function printDialog() {
	printDialogClearclosewin(); 
	var dialog = Ext.get('printDialog');
	if( dialog.initialized ) { dialog.show(); }
	else {
		var pelm = Ext.get('printbutton');
		var top = pelm.getBottom(false);
		var left = pelm.getLeft(false);
		dialog.moveTo(left, top-8);
		dialog.show();
		dialog.initialized = true;
	}	
}
function printDialogClearclosewin( ){if (typeof at12E!="undefined")clearTimeout(at12E); }
function printDialogOnmouseout() { printDialogClosewinwait(); }
function printDialogClosewinwait( ){ at12E=setTimeout("closePrintDialog()",0764); }
function closePrintDialog() { Ext.get('printDialog').hide(); }

function printPreviewWindow(destination) {
	var sendto = (destination && destination.length) ? destination : null;
	w=window.open(destination,'printpreview','width=850, height=700, scrollbars=yes, menubar=yes');
	w.moveTo(200,200);
}


/* carousel functions */

var Carousel = function(config){
	this.config = config;
	this.init();
	this.view.render(this.config.id);
}

Carousel.prototype = {
	init: function() {
	this.initTemplates();
	this.store = new Ext.data.Store({
		proxy: new Ext.data.PagingMemoryProxy(this.config.data),
		remoteSort: true,
		baseParams: { start: 0, limit: this.config.display},
        reader: new Ext.data.JsonReader({ root: 'data', totalProperty: 'recordcount'
        }, [{name: 'id', mapping: 'ID'},
			{name: 'name', mapping: 'NAME'},
			{name: 'link', mapping: 'LINK'},
			{name: 'imagepath', mapping: 'IMAGEPATH'}])
	});

	this.store.load({params:{start:0, limit:this.config.display}});
	this.updatepaging();
	
	this.lookup = {}

	this.cleanString = function(str) {
	 str = str.replace(/&trade;/g,"");
	 str = str.replace(/&copy;/g,"");
	 str = str.replace(/&reg;/g,"");
	 str = str.replace(/&lsquo;/g,"");
	 str = str.replace(/&rsquo;/g,"");
	 str = str.replace(/&ldquo;/g,"");
	 str = str.replace(/&rdquo;/g,"");
	 str = str.replace(/&ndash;/g,"-");
	 str = str.replace(/&mdash;/g,"-");
	 str = str.replace(/&frac14;/g," 1/4");
	 str = str.replace(/&frac12;/g," 1/2");
	 str = str.replace(/&frac34;/g," 3/4");
	 str = str.replace(/&eacute;/g,"e");
	 str = str.replace(/&egrave;/g,"e");
	 str = str.replace(/&hellip;/g,"");
	 str = str.replace(/&deg;/g,"");
	 str = str.replace(/&dagger;/g,"");
	 str = str.replace(/\u2122/g,""); // hex equavalent
	 str = str.replace(/\uA9/g,""); // hex equavalent
	 str = str.replace(/<[^>]*>/g," "); // remove any html formatting
	 str = str.replace(/[^a-zA-Z 0-9_,./\-()\\]/g,""); // allow only these characters
	 str = str.replace(/ +/g,"+"); // strip repeat white space
	 return str;
	};
	
	var formatData = function(data, recordindex, record){
    	data.shortName = data.name.ellipse(17);
		data.trackingcode = '';
		if( this.config.trackingname != '') {
			var pos = String(this.store.baseParams.start + recordindex + 1);
			var lid = this.config.trackingname + pos + ': ' + this.cleanString(data.name);
			data.trackingcode = 'name="&lid=' + lid + '&lpos=' + pos + '"';
		}
		this.lookup[data.id] = data;
    	return data;
    };

    this.view = new Ext.DataView({
		tpl: this.thumbTemplate,
		singleSelect: true,
		overClass:'x-view-over',
		itemSelector: 'div.thumb-wrap',
		emptyText : '<div style="padding:10px;">No images match the specified filter</div>',
		store: this.store,
		listeners: {
			'selectionchange': {fn:this.showDetails, scope:this }
		},

		prepareData: formatData.createDelegate(this)
		});
	},

	showDetails: function(view, selections) {
		var data = this.lookup[selections[0].id];
		location=data.link;		
	},
	
	initTemplates : function(){
		this.thumbTemplate = new Ext.XTemplate(
			 '<tpl for=".">',
				'<div class="thumb-wrap" id="{id}">',
				'<div class="thumb wraptocenter"><span></span><a href="{link}" {trackingcode}><img src="{imagepath}" title="{name}" /></a></div>',
				'<span class="label"><a href="{link}" {trackingcode}>{shortName}</a></span></div>',
			'</tpl>'
		);
		this.thumbTemplate.compile();		
	},
	
	onLoadException : function(v,o){
	    this.view.getEl().update('<div style="padding:10px;">Error loading images.</div>'); 
	},

	previous: function() {
		this.store.baseParams.start = this.store.baseParams.start - this.config.display;
		Ext.get(this.config.id).slideOut('r', { duration: .5,
											    callback: function() {
													this.updatepaging();
													this.store.load( { callback: this.previouscallback, scope: this });
												}, scope: this
											 });
	},

	previouscallback: function() {
		Ext.get(this.config.id).slideIn('l', { duration: 1 });
	},

	next: function() {		
		this.store.baseParams.start = this.store.baseParams.start + this.config.display;
		Ext.get(this.config.id).slideOut('l', { duration: 0.5, 
											    callback: function() {
													this.updatepaging();
													this.store.load( { callback: this.nextcallback, scope: this });
												}, scope: this
											});
	},
	
	nextcallback: function() {
		Ext.get(this.config.id).slideIn('r', { duration: 1 });
	},
	
	updatepaging: function() {
		var start = this.store.baseParams.start;
		var display = this.config.display;
		if (start + display >= this.store.getTotalCount()) { Ext.get(this.config.id + '-next').hide(); } 
		else { Ext.get(this.config.id + '-next').show(); }
		if (start - display < 0 ) { Ext.get(this.config.id + '-prev').hide(); }
		else { Ext.get(this.config.id + '-prev').show(); }
	}
};

String.prototype.ellipse = function(maxLength){
	return this.length > maxLength ? this.substr(0, maxLength-3) + '...' : this;
};


/* static carousel functions */

var StaticCarousel = function(config){
	this.start = 0;
	this.cellwidth = 106;
	this.config = config;
	this.shift = this.cellwidth*this.config.display;
	this.updatepaging();
}

StaticCarousel.prototype = {
	previous: function() {
		this.start -= this.config.display;	
		var elm = Ext.get(this.config.id+'-canvas');
		elm.setLeft(elm.getLeft(true)+this.shift);
		this.updatepaging();
	},

	next: function() {	
		this.start += this.config.display;	
		var elm = Ext.get(this.config.id+'-canvas');
		elm.setLeft(elm.getLeft(true)-this.shift);
		this.updatepaging();
	},
	
	updatepaging: function() {
		if (this.start + this.config.display >= this.config.total) { Ext.get(this.config.id + '-carouselview-next').hide(); } 
		else { Ext.get(this.config.id + '-carouselview-next').show(); }
		if (this.start - this.config.display < 0 ) { Ext.get(this.config.id + '-carouselview-prev').hide(); }
		else { Ext.get(this.config.id + '-carouselview-prev').show(); }
	}
};

// Paging memory proxy stuff

/* Fix for Opera, which does not seem to include the map function on Array's */
if(!Array.prototype.map){
    Array.prototype.map = function(fun){
	var len = this.length;
	if(typeof fun != "function"){ throw new TypeError(); }
	var res = new Array(len);
	var thisp = arguments[1];
	for(var i = 0; i < len; i++){ if(i in this){ res[i] = fun.call(thisp, this[i], i, this); } }
    return res;
    };
}

/* Paging Memory Proxy, allows to use paging grid with in memory dataset */

Ext.data.PagingMemoryProxy = function(data) {
	Ext.data.PagingMemoryProxy.superclass.constructor.call(this);
	this.data = data;
};

Ext.extend(Ext.data.PagingMemoryProxy, Ext.data.MemoryProxy, {
	load : function(params, reader, callback, scope, arg) {
		params = params || {};
		var result;
		try {
			result = reader.readRecords(this.data);
		}catch(e){
			this.fireEvent("loadexception", this, arg, null, e);
			callback.call(scope, null, arg, false);
			return;
		}
		// filtering
		if (params.filter!==undefined) {
			result.records = result.records.filter(function(el){
			    if (typeof(el)=="object"){
					var att = params.filterCol || 0;
					return String(el.data[att]).match(params.filter)?true:false;
			    } else { return String(el).match(params.filter)?true:false; }
			});
			result.totalRecords = result.records.length;
		}
		// sorting
		if (params.sort!==undefined) {
		    // use integer as params.sort to specify column, since arrays are not named
		    // params.sort=0; would also match a array without columns
		    var dir = String(params.dir).toUpperCase() == "DESC" ? -1 : 1;
        	var fn = function(r1, r2){
				return r1 < r2;
            };
		    result.records.sort(function(a, b) {
				var v = 0;
				if (typeof(a)=="object"){ v = fn(a.data[params.sort], b.data[params.sort]) * dir;
				} else { v = fn(a, b) * dir; }
				if (v==0) { v = (a.index < b.index ? -1 : 1); }
				return v;
		    });
		}
		// paging (use undefined cause start can also be 0 (thus false))
		if (params.start!==undefined && params.limit!==undefined) {
			result.records = result.records.slice(params.start, params.start+params.limit);
		}
		callback.call(scope, result, arg, true);
	}
});
