/**
  * Project      :  AMDA-NG
  * Name         : AstroImagesUI.js
  * @plugin 	  amdaUI.AstroImagesUI
  * @extends 	  Ext.panel.Panel
  * @brief		 Astronomical images viewer for interoperability - Abstract class
  * @author Benjamin
  * @version $Id: AstroImagesUI.js 1847 2013-10-30 14:46:48Z elena $
  ********************************************************************************
  *    FT Id     :   Date   : Name - Description
  *******************************************************************************
  *  :          
  */

Ext.define('ImageNode', {
		    extend: 'Ext.data.Model',
		    
		    fields: [
		        {name: 'leaf',      type: 'boolean'},
		        {name: 'id',        type: 'string'},
		        {name: 'name',      type: 'string'},
		        {name: 'target',    type: 'string'},
		        {name: 'ra',        type: 'string'},
		        {name: 'dec',       type: 'string'},
		        {name: 'ref',       type: 'string'},
		        {name: 'start',     type: 'string'},
		        {name: 'stop',      type: 'string'},
		        {name: 'exposure',  type: 'string'},
		        {name: 'instrument',type: 'string'},
		        {name: 'thumbnail_url', type: 'string'},
		        {name: 'image_url', type: 'string'},
		        {name: 'fits_url', type: 'string'},
		        {name: 'additional_text', type: 'string'}
		    ]
		});

Ext.define('amdaUI.AstroImagesUI', {
    extend: 'Ext.form.Panel',
    
    requires: [
               'amdaUI.SendToSampButtonUI',
		'amdaModel.DownloadNode'
           ],
    
    //
    getPreviewUrl : Ext.emptyFn,
    getImageLink  : Ext.emptyFn,
    getImageToSendUrl    : Ext.emptyFn,
    refreshTree   : Ext.emptyFn,
    getAcknowledgement : Ext.emptyFn,
           
    timeSelector : null,
    preview      : false,
    
    constructor: function(config) {			
		this.init(config);
		this.callParent(arguments);
	},
    
	setInterval : function(startDate,stopDate)
	{
		this.timeSelector.setInterval(startDate,stopDate);
	},
	
	setPreview : function(prev)
	{
		if (!this.getPreviewUrl)
			return;
		
		this.preview = prev;
		
		var view = this.getImageTreePanel().getView();
		var rootNode = this.getImageTreePanel().store.getRootNode();
			
		rootNode.eachChild(function(folder)
				{
					folder.eachChild(function(image)
							{
								if (prev)
								{
									var imageSrc = this.getPreviewUrl(image);
									image.set('icon',imageSrc);
									image.set('iconCls','x-tree-icon-leaf');
								}
								else
								{
									image.set('icon','');
									image.set('iconCls','');
								}
							},this);
				},this);
	},
	
	getSelectedImageList : function()
	{
		var me = this;
		var root = this.getImageTreePanel().getRootNode();
		var imgList = new Array();
		
		if (!this.getImageToSendUrl)
			return imgList;
		
		root.eachChild(function (folder){
			folder.eachChild(function (image){
				if(image.get('checked'))
				{
					var name = image.get('name');
					if (!name.substr(name.lastIndexOf('.') + 1) != "fits")
						name+='.fits';
					imgList.push({name:name, 
								  url:me.getImageToSendUrl(image)});
				}
			});
		});
		
		return imgList;
	},
	
	getCurrentScript : function()
	{
		var imageList = this.getSelectedImageList();
		if (imageList.length <= 0)
			{
			  	Ext.Msg.show({title:'Empty selection', msg: 'You must select at least one image in tree', icon: Ext.MessageBox.WARNING, buttons: Ext.Msg.OK});
				return;
			}
		var interopModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.interop.id);
		if (interopModule) {
			return interopModule.generateAladinScript(imageList,'movie');
		};
		return "";
	},
	
	onExtendInterval : function(o)
	{
		var dtField = o.up().up().query('numberfield')[0];
		var dtVal = dtField ? dtField.getValue() : 0;
		
		var unitField = o.up().up().query('combobox')[1];
		var unitVal = unitField ? unitField.getValue() : 'min';
		
		switch(unitVal)
		{
			case 'min' :
				dtVal *= 60;
				break;
			case 'hour' :
				dtVal *= 3600;
				break;
			case 'day' :
				dtVal *= (24*3600);
				break;
		}
		
		var startTime = this.timeSelector.getStartTime();
		var stopTime = this.timeSelector.getStopTime();
		
		switch(o.getText())
		{
			case 'left'  :
				startTime = Ext.Date.add(startTime, Ext.Date.MILLI, -dtVal*1000);
				break;
			case 'right' :
				stopTime  = Ext.Date.add(stopTime, Ext.Date.MILLI, dtVal*1000);
				break;
			case 'both'  :
				startTime = Ext.Date.add(startTime, Ext.Date.MILLI, -dtVal*1000);
				stopTime  = Ext.Date.add(stopTime, Ext.Date.MILLI, dtVal*1000);
				break;
		}
		
		this.timeSelector.setInterval(startTime,stopTime);
	},
	
	onShiftInterval : function(o)
	{
		var dtField = o.up().up().query('numberfield')[0];
		var dtVal = dtField ? dtField.getValue() : 0;
		
		var unitField = o.up().up().query('combobox')[1];
		var unitVal = unitField ? unitField.getValue() : 'min';
                
		switch(unitVal)
		{
			case 'min' :                            
				dtVal *= 60;                               
				break;
			case 'hour' :
				dtVal *= 3600;
				break;
			case 'day' :
				dtVal *= (24*3600);
				break;
		}
		
		var startTime = this.timeSelector.getStartTime();
		var stopTime = this.timeSelector.getStopTime();
		
		switch(o.getText())
		{
			case 'left'  :
				startTime = Ext.Date.add(startTime, Ext.Date.MILLI, -dtVal*1000);
				stopTime  = Ext.Date.add(stopTime, Ext.Date.MILLI, -dtVal*1000);
				break;
			case 'right' :
				startTime = Ext.Date.add(startTime, Ext.Date.MILLI, dtVal*1000);
				stopTime  = Ext.Date.add(stopTime, Ext.Date.MILLI, dtVal*1000);
				break;
		}
		
		this.timeSelector.setInterval(startTime,stopTime);
	},
	
	createTree : function(imagesArray)
	{
		this.getImageTreePanel().setLoading(false);
		var rootNode = this.getImageTreePanel().store.getRootNode();
		rootNode.removeAll(false);
	    	
		Ext.each(imagesArray, function(data){
			var rec =	Ext.create('ImageNode',{
					leaf  : false,
					id    : data.name,
					name  : data.name,
					start : data.start
				  });
			var folderNode = rootNode.appendChild(rec);
			Ext.each(data.images, function(image,index){
				var rec =	Ext.create('ImageNode',{
					 leaf        : true,
					 id          : data.name+'-'+image.name+'-'+index+'-'+this.id,
					 name        : image.name,
					 target      : image.target,
					 ra          : image.ra,
					 dec         : image.dec,
					 ref         : image.ref,
					 start       : image.start,
					 stop        : image.stop,
					 exposure    : image.exposure,
					 instrument  : image.instrument,
					 thumbnail_url : image.thumbnail_url,
					 fits_url    : image.fits_url,
					 image_url   : image.image_url,
					 additional_text : image.additional_text,
					 checked     : false,
					 hrefTarget  : '_blank'
				  });
				if (this.getImageLink)
					rec.set('href',this.getImageLink(rec));
						 
				folderNode.appendChild(rec);
			},this);
		}, this);
		
		this.getImageTreePanel().getView().refresh();
		
		this.setPreview(this.preview);
	},
	
	onRefreshTree : function(o)
	{
		if (this.refreshTree)
			this.refreshTree();
	},
	
	onSendFITSToSAMP : function(clientId, sendOpt)
	{
		if (!sendOpt.scope)
			return;
		
		var imageList = sendOpt.scope.getSelectedImageList();
		if (imageList.length <= 0)
			{
				Ext.Msg.show({title:'Empty selection', msg: 'You must select at least one image in tree', icon: Ext.MessageBox.WARNING, buttons: Ext.Msg.OK});
				return;
			}
		
		myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.interop.id, true, function (module) {
			/*var script = this.getCurrentScript();
			module.sendAladinScript(escape(script));*/	
			for( var i=0; i < imageList.length; i++)
			{
				var url = imageList[i].url;
				var name = imageList[i].name;
				if (module)
					module.sendFITS(url,name);
			}
		});
		
		
	},
	
	onSendToWeb : function(o)
	{
		var me = this;
		myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.interop.id, true, function (module) {
			var script = me.getCurrentScript();
			var args = "";
	        if( script )
	        {
	            args="?script="+escape(script);
	        }
	        var url = "http://aladin.u-strasbg.fr/java/nph-aladin.pl"+args;
	        window.open( url );
		});
	},
	
	onDownload : function(o)
	{
		var imageList = this.getSelectedImageList();
		
		if (imageList.length <= 0)
		{
			Ext.Msg.show({title:'Empty selection', msg: 'You must select at least one image in tree', icon: Ext.MessageBox.WARNING, buttons: Ext.Msg.OK});
			return;
		}
			
		var obj = Ext.create('amdaModel.Download');
		obj.set('compression','zip');
		obj.set('list',imageList);
		obj.set('downloadSrc',2);

		var downloadNode = Ext.create('amdaModel.DownloadNode', {
                        leaf : true,
                });

		downloadNode.set('object',obj);	
		downloadNode.execute();
	},
	
	getAdditionalRequestConfig : function(panelId)
	{
		return {};
	},
	
	getTargetList : function()
	{
		return [];
	},
	
	createRequestSelectorPanel : function(panelId)
	{
		var me = this;
		this.timeSelector = Ext.create('amdaUI.IntervalUI', {});
		
		return {
			xtype : 'panel',
			region : 'west',
			title : 'Request definition',
			bodyStyle: { background : '#dfe8f6' },
			flex:1,
			layout: { type: 'vbox', align: 'stretch'},
	    	dockedItems: [{
		          xtype: 'toolbar', 
		          dock: 'bottom',
		          items: [
		             '->',
		            {
		              text: 'Refresh',
		              scope : me,
		              handler : me.onRefreshTree
		          }]
	    		}],
		    items : [
		             { xtype: 'component', height: 5},
		             {
		            	xtype : 'combo',
		            	id : panelId+'-combo-target',
		            	fieldLabel : 'Target',
		            	fields : ['id', 'name'],
		            	queryMode: 'local',
		            	editable: false,
		            	store : this.getTargetList(),
		            	value: "saturn"
		             },
		             {
		            	 xtype : 'component',
		            	 autoEl: 'hr'
		             },
		             this.timeSelector,
		             {
		            	 xtype : 'component',
		            	 autoEl: 'hr'
		             },
		             {
		            	 xtype : 'container',
		            	 layout : 'hbox',
		            	 items : [
		            	          {
		            	        	  xtype : 'numberfield',
		            	        	  fieldLabel : 'Delta T',
		            	        	  labelWidth: 60,
		            	        	  flex : 1,
		            	        	  minValue: 0,
		            	        	  value : 0,
		            	        	  hideTrigger: true,
		            	              keyNavEnabled: false,
		            	              mouseWheelEnabled: false
		            	          },
		            	          { xtype: 'component', width: 5},
		            	          {
		            	        	  xtype : 'combobox',
		            	        	  queryMode: 'local',
		            	        	  forceSelection : true,
		            	        	  flex : 1,
		            	        	  allowBlank : false,
		            	        	  editable: false,
		            	        	  value : "min",
		            	        	  store : [
		            	        	          ["min","minute(s)"],
		            	        	          ["hour","hour(s)"],
		            	        	          ["day","day(s)"]
		            	        	          ]
		            	          }
		            	       ]
		             },
		             { xtype: 'component', height: 5},
		             {
		            	 xtype : 'container',
		            	 layout : 'hbox',
		            	 items : [
		            	          {
		            	        	  xtype : 'label',
		            	        	  text  : 'Extend ... ',
		            	        	  width : 60
		            	          },
		            	          { xtype: 'component', width: 5},
		            	          {
		            	        	  xtype : 'button',
		            	        	  text  : 'left',
		            	        	  flex  : 1,
		            	        	  scope : me,
		            	        	  handler : me.onExtendInterval
		            	          },
		            	          { xtype: 'component', width: 5},
		            	          {
		            	        	  xtype : 'button',
		            	        	  text  : 'right',
		            	        	  flex  : 1,
		            	        	  scope : me,
		            	        	  handler : me.onExtendInterval
		            	          },
		            	          { xtype: 'component', width: 5},
		            	          {
		            	        	  xtype : 'button',
		            	        	  text  : 'both',
		            	        	  flex  : 1,
		            	        	  scope : me,
		            	        	  handler : me.onExtendInterval
		            	          }
		            	       ]
		             },
		             { xtype: 'component', height: 5},
		             {
		            	 xtype : 'container',
		            	 layout : 'hbox',
		            	 items : [
		            	          {
		            	        	  xtype : 'label',
		            	        	  text  : 'Shift ... ',
		            	        	  width : 60
		            	          },
		            	          { xtype: 'component', width: 5},
		            	          {
		            	        	  xtype : 'button',
		            	        	  text  : 'left',
		            	        	  flex  : 1,
		            	        	  scope : me,
		            	        	  handler : me.onShiftInterval
		            	          },
		            	          { xtype: 'component', width: 5},
		            	          {
		            	        	  xtype : 'button',
		            	        	  text  : 'right',
		            	        	  flex  : 1,
		            	        	  scope : me,
		            	        	  handler : me.onShiftInterval
		            	          }
		            	       ]
		             },
		             {
		            	 xtype : 'component',
		            	 autoEl: 'hr'
		             },
		             this.getAdditionalRequestConfig(panelId)
		    ]
		};
	},
	
	createImageTreePanel : function(panelId)
	{
		var me = this;
		return {
			xtype : 'treepanel',
			region : 'center',
			title : 'Image Selection',
		    flex:1,
		    rootVisible: false,
		    autoScroll : true,
		    animate: false,
		    id : panelId+'-images-tree-panel',
		    columns: [{
	            xtype: 'treecolumn',
	            text: 'Images',
	            flex: 1,
	            sortable: false,
	            dataIndex : 'id',
	            renderer : function(value,metaData,record,rowIndex,colIndex,store,view)
                {
                	if (record.get('leaf'))
                	{
                		if (record.get('additional_text'))
                			return record.get('start') + ' - ' + record.get('additional_text');
                		else
                			return record.get('start');
                	}
                	var start = record.get('start');
                	var dt = Ext.Date.parse(start,'Y-m-d H:i:s');
                	return Ext.Date.format(dt, 'Y-m-d') + ' <b>('+record.childNodes.length+' image'+(record.childNodes.length > 1 ? 's' : '')+')</b>';
                } 
	        }],
	        store : Ext.create('Ext.data.TreeStore', {
	            root: {
	            	expanded: true,
	            	children: []
	        		},
	        	model : 'ImageNode'
	        }),
		    tbar : [
		            {
		            	text : 'Collapse all',
		            	flex : 1,
		            	scope : me,
		            	handler : function(o)
		            	{
		            		this.getImageTreePanel().collapseAll();
		            	}
		            },
		            {
		            	text : 'Expand all',
		            	flex : 1,
		            	scope : me,
		            	handler : function(o)
		            	{
		            		this.getImageTreePanel().expandAll();
		            	}
		            },
		            {
		            	text : 'Select all',
		            	flex : 1,
		            	scope : me,
		            	handler : function(o)
		            	{
		            		var root = this.getImageTreePanel().getRootNode();
		            		root.eachChild(function (folder){
		            			folder.eachChild(function (image){
		            				image.set('checked',true);
		            			});
		            		});
		            	}
		            },
		            {
		            	text : 'Unselect all',
		            	flex : 1,
		            	scope : me,
		            	handler : function(o)
		            	{
		            		var root = this.getImageTreePanel().getRootNode();
		            		root.eachChild(function (folder){
		            			folder.eachChild(function (image){
		            				image.set('checked',false);
		            			});
		            		});
		            	}
		            }
		            
		            ],
		     dockedItems: [{
		                xtype: 'toolbar',
		                dock: 'bottom',
		                items: [
		                        {
		                        	xtype : 'checkbox',
		                        	boxLabel: 'Load preview',
		                        	listeners : {
		                        		'change' : function(o,newVal,oldVal,opts)
		                        		{
		                        			me.setPreview(newVal);
		                        		}
		                        	}
		                        },
		                        '->',
		                        {
		                        	xtype : 'button',
		                        	text  : 'Download selection',
	      	  	        			scope : this,
	      	  	        			handler : me.onDownload
		                        }
		                        ]
		    }],
		    listeners :
		    {
			    'afterrender' : function(tree) 
				{
					view = tree.getView();
						
					
					view.tip = Ext.create('Ext.tip.ToolTip', {
						// The overall target element.
						target: view.el,
						// Each grid row causes its own seperate show and hide.
						delegate: view.itemSelector,
						// Moving within the row should not hide the tip.
						trackMouse: false,//true,
						// Render immediately so that tip.body can be referenced prior to the first show.
						//renderTo : Ext.getBody(),
						//showDelay : 2,
						//hideDelay : 0,
						listeners: {
							// Change content dynamically depending on which element triggered the show.
							beforeshow: function (tip) 
							{
								view = tree.getView();
								record = view.getRecord(tip.triggerElement);
								if (record)
								{
									if (!record.get('leaf'))
									{
										var crtTip = '<b>Name : </b>"' + record.get('name') + '"<br/>';
										crtTip    += '<b>Start time : </b>"' + record.get('start') + '"<br/>';
										tip.update(crtTip);
										return;
									}
									var crtTip = '<b>Name : </b>' + record.get('name') + '<br/>';
									crtTip    += '<b>Start time : </b>' + record.get('start') + '<br/>';
									crtTip    += '<b>Stop time : </b>' + record.get('stop') + '<br/>';
									crtTip    += '<b>Exposure time : </b>' + record.get('exposure') + '<br/>';
									crtTip    += '<b>Target : </b>' + record.get('target') + '<br/>';
									crtTip    += '<b>Instrument : </b>' + record.get('instrument') + '<br/>';
									
									if (me.preview && me.getPreviewUrl)
										crtTip    += '<img width=300 height=300 src="'+me.getPreviewUrl(record)+'" /><br/>';
									
									tip.update(crtTip);
								}
		            		}
						}
					});
				}
		    }
		};
	},
	
	getImageTreePanel : function()
	{
		return this.queryById(this.id+'-images-tree-panel');
	},
	
	getTargetCombo : function()
	{
		return this.queryById(this.id+'-combo-target');
	},
	
	forceRefresh : function()
	{
		this.onRefreshTree(this);
	},
	
    init : function(config)	
    {
	  var me = this;
		
	  var myConf = {
    		  defaults: {
    	  	    bodyStyle: { background : '#dfe8f6' }
    	  	  },
    	  	  layout : 'border',
    	  	  items: [
    	  	          {
    	  	        	xtype : 'panel',
  	  	        	    region : 'north',
  	  	        	    height : 40,
  	  	        	    html : this.getAcknowledgement ? this.getAcknowledgement() : 'ToDo - Acknowledgement'
    	  	          },
    	  	          this.createRequestSelectorPanel(config.id),
    	  	          this.createImageTreePanel(config.id),
    	  	          {
    	  	        	  xtype : 'panel',
    	  	        	  region : 'south',
    	  	        	  layout : 'hbox',
    	  	        	  title : 'Interoperability',
      	  	        	  height : 60,
      	  	        	  items :
      	  	        		  [
      	  	        		   {
      	  	        			   xtype : 'combobox',
      	  	        			   fieldLabel : 'Display Mode',
      	  	        			   flex : 2,
      	  	        			   disabled : true,
      	  	        			   allowBlank : false,
      	  	        			   editable: false,
      	  	        			   store : [
      	  	        			            ["mosaic","mosaic"],
      	  	        			            ["movie","movie"],
      	  	        			            ["diff","diff"]
      	  	        			            ]
      	  	        		   },
      	  	        		   { xtype: 'component', width: 5},
      	  	        		   {
      	  	        			   xtype : 'button',
      	  	        			   flex : 1,
      	  	        			   text  : 'Send to Aladin Web',
      	  	        			   scope : this,
      	  	        			   handler : this.onSendToWeb
      	  	        		   },
      	  	        		   { xtype: 'component', width: 5},
      	  	        		   {
      	  	        			   xtype : 'sendToSampButton',
      	  	        			   flex : 1,
      	  	        			   type         : 'fits',
      	  	        			   onSendToSamp : me.onSendFITSToSAMP,
      	  	        			   sendOpt : {scope : me}
      	  	        		   }
      	  	        		  ]
    	  	          }
    	  	  ]
    	  	  };
      Ext.apply (this , Ext.apply (arguments, myConf));
    }
});