/**
 * Project   : AMDA-NG
 * Name      : amdaUI.ParamsMgrUI
 * @class    :  
 * @extends  Ext.Panel.Panel 
 * @brief     
 * @author Elena 
 * @version  $Id: ParamsMgrUI.js 1871 2013-11-22 13:54:17Z elena $
 ******************************************************************************
 *    FT Id     :   Date   : Name - Description
 ******************************************************************************
 *	          
 */

Ext.define('amdaUI.ParamsMgrUI', {
    extend: 'Ext.panel.Panel',
      
    alias: 'widget.paramsMgrPanel',
    
    baseId : null,
    srcTree : null,
    destTree : null,
    
   
    hasModifs: false,
    
    //TODO where keep this (==baseId) description ? Global variable?
    basesNames : ['VEXGRAZ', 'CDAWEB', 'THEMIS', 'MAPSKP'],
    bases : [],
    
    configSrc : {title: 'source', enableDrag : true, enableDrop: false},
    configDest : {title: 'destination', enableDrag : false, enableDrop:true},
	
       
    constructor: function(config) {	    
	    this.init(config);
	    this.callParent(arguments);
    },
      	   
   /*
    * Load new data bases trees	: source & destination
    */   
    loadTrees : function(button, pressed) {
      if (pressed) {		    
	this.baseId =  button.text;	
	this.loadTree('source');
	this.loadTree('destination');
      }
    },
    
   /*
    * Real Load  data base tree	
    */   
    loadTree : function(type) {
      
      var title = this.baseId;
      if (type == 'source') var store = this.srcTree.getStore();
      else {
	    var store = this.destTree.getStore();
	    title = 'My '+ this.baseId;
      }	
      // or RELOAD?
      var root = store.getRootNode();		   
      store.load({
	node: root,
	params: {
	  nodeType: type,
	  baseId: this.baseId
	}
      });	
      root.set('text', title);		    		  
    },
    
/*
 *   Store and tree creation
 */
    initTree:  function(config) {
		  
	if (this.baseId) {
	  var title = config.title == 'source' ? this.baseId : 'My '+ this.baseId;
	}
	else var title = config.title;
	   
	var selMode =  config.title == 'source' ? {mode: 'SIMPLE'} : {mode: 'SINGLE'};

	var store = Ext.create('Ext.data.TreeStore', {
	  model: 'amdaModel.AmdaNode',		     
	  root: {			  			  
	      text: title,
	      //TODO if use the same logic for localParam?
	      nodeType : 'remoteParam',
	      expanded: true
	  },
	  listeners: {
	    scope : this,
	    beforeload: function(store, operation){
	      store.proxy.extraParams = {
		  nodeType: config.title,
		  baseId: this.baseId
	      }
	    }}
	  });
	
	var menu = new Ext.menu.Menu({
	  items: [{
	    text: 'Delete Data'
	  }],
	  listeners: {
	    scope : this,
	    click : this.deleteMulti
	  }
	});
	
	var tree = Ext.create('Ext.tree.Panel', {
	    store: store,
	    id : config.title,
	    flex: 1,
	    height: 400,
	    selModel: selMode, //{mode: 'SIMPLE'},
	    viewConfig: {
		plugins: {
		    ptype: 'treeviewdragdrop',
		    allowContainerDrops : true,
		    enableDrag: config.enableDrag,
		    enableDrop: config.enableDrop,
		    //TODO dataset drag/drop by parameters SELECTION
		    dragText : "{0} selected parameter{1}",
		    expandDelay : 100,		   
		    ddGroup : "RemoteTreeDD",   
		    isValidDropPoint : function(){		            
		        return true;
		    },		    
		    onContainerOver : function() {					 
		      return this.dropAllowed;
		      
		    },
		    onNodeOver : function() {					 
		      return this.dropAllowed;		      
		    }, 		 
		    onNodeDrop : function(nodeData, dd, e, data) { 
		       if (!data.records)
				  return false;
		      Ext.Array.each(data.records, this.onDrop, this);
// deselect source tree selection		      
		      data.view.getSelectionModel().deselectAll();
		      return true;		      
		    },		    
		    onContainerDrop : function(dd, e, data) {	
		      
		      if (!data.records)
				  return false;		
			Ext.Array.each(data.records, this.onDrop, this); 
// deselect source tree selection		      
		        data.view.getSelectionModel().deselectAll();
		        return true;
		    },

		    onDrop : function(record) {
		      
 		      var root = tree.getRootNode();		   
		      var srcNode = record;		   
		      var id = srcNode.get('id');	
		      
		      // Check if node exists already at destination		      
		      if (root.findChild('id',id, true)) return;
		      
		      var ddNode = srcNode;
  // Array of parent nodes description			  
		      var Arr = []; 
		      	      
		      while (!ddNode.isRoot()) {			   
			    ddNode = ddNode.parentNode;
			    Arr.push(ddNode);
			}
  // start with the highest node			    
		      Arr.reverse();			  						   

  // create parent nodes if they do not exist
		      var parentNode = root;
		      Ext.Array.each(Arr,function(srcNode, index){
			    if (index > 0) {
			       var nodeId = srcNode.get('id');	  			
			       var node = root.findChild('id',nodeId, true);				  
			        if (!node) {					 			
			          node = srcNode.copy();
			 	  parentNode.appendChild(node);
				  parentNode.expand(); 				    				    				
				  node.setDirty();
			      }				      			      			 
			      parentNode = node;				
			    } 			      
		      });
	 			      
		    // Add new node to correct location			    
		      parentNode.expand(!this.isDataSet, function(res){  		  	     	    		   		  
			  var newNode = srcNode.copy();
			  parentNode.appendChild(newNode); 	
			  //to sync treeStore			  
			  newNode.setDirty();
			  //expand the whole subtree of added node
			  tree.selectPath(newNode.getPath( 'id', '|'), 'id', '|');
		    });
		    return true;		     
		    },
		    
		    onViewRender : function(view) {
		      var me = this;

		      if (me.enableDrag) {
			      me.dragZone = Ext.create('Ext.tree.ViewDragZone', {
			      view: view,
			      ddGroup: me.dragGroup || me.ddGroup,
		 	      dragText: me.dragText
			    });
		      }

		      if (me.enableDrop) {
			      me.dropZone = Ext.create('Ext.tree.ViewDropZone', {
			      view: view,
			      ddGroup: me.dropGroup || me.ddGroup,
			      allowContainerDrops: me.allowContainerDrops,
			      expandDelay: me.expandDelay,
			      isValidDropPoint : me.isValidDropPoint,
			      onContainerDrop : me.onContainerDrop,
			      onNodeDrop      : me.onNodeDrop,
			      onContainerOver : me.onContainerOver,
			      onNodeOver : me.onNodeOver,
			      onDrop : me.onDrop,
			      onSimpleDrop : me.onSimpleDrop
			    });
		      }
		      }
		  }
	      }, 		
	      listeners: {
		afterrender: function(comp){		   
		    var view = comp.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: true,			   
			autoRender: true,				   
			listeners: {
			    // Change content dynamically depending on which element triggered the show.
			    beforeshow: function updateTipBody(tip) {	
			      var trigger =  view.getRecord(tip.triggerElement);
			      if (trigger) {
				var info = trigger.get('info');
				if (!info || info == '') {						      
				    tip.addCls('hide');							  
				  }
				  else { 
				    tip.removeCls('hide');			 					  	 					        					       						 
				    tip.update(info); 
				  }					      					  
				}
			    }
		    }
		    });
		},
				 
		itemmouseenter: function(view, record, item){		  
		  if(record.get('allowDrag') && view.ownerCt.id == 'source'){		 
		        var el = Ext.get(item),
                        td = el.down('td > div');
                        td.setStyle('cursor', 'crosshair');				
		  }
		},
		
		beforeselect: function(selmodel, record, index) {		    
	 	    if (!(record.get('isRemoteDataSet') || record.get('isParameter')) && tree.id == 'source') return false;			 	  			      
		},
  
	  	select: function(selmodel, record, index) {
		   
	  	   if (record.get('isRemoteDataSet') && tree.id == 'source' && record.isExpanded()) {
		            var toSelect = selmodel.getCount() !== record.childNodes.length + 1;
			    var alreadySelected = selmodel.isSelected(record.firstChild);
			    
			    selmodel.deselectAll();
			      
			    if (toSelect && !alreadySelected) selmodel.select(record.childNodes);			 
		   }
	  	},
	 	
		itemcontextmenu: function(view, rec, item, index, e){		  
		    e.preventDefault();//stopEvent();
		    if (tree.id == 'destination' && rec.getDepth() > 0)  		        
					      menu.showAt(e.getXY());			 		 		        
		    }
	  }
	});	
	return tree;
    },
// for the moment SINGLE!    
    deleteMulti: function(){
	    var selected = this.destTree.getSelectionModel().getSelection();
	    Ext.Array.each(selected, function(rec){
				      rec.deleteData();
	    });      
    },
    
    
    successCallBack : function(batch, options) {   
	    this.hasModifs = true;   
	    loadMask.hide();               
	    var createdNodes = options.operations.update;
	     
// define Pathes to the created nodes	     
	     var Arr = [];	     
	     Ext.Array.each(createdNodes,function(item){	                            	           
		      if (item.getDepth() == 4) { // parameter level			    
			   Arr.push(item.getPath('id', '|'));		 	 		 
		      }
	     });
	     
// reload destination tree and expand created nodes	     
	     var panel = this.destTree;	     
	     var store = this.destTree.getStore();
	     var root = store.getRootNode();	     
	     store.load({ node : root, 
			  params : { nodeType: 'destination',
				      baseId: this.baseId },
			  callback : function(){			    			 
			    for (var i = 0; i < Arr.length; i++){			     
			        panel.selectPath(Arr[i], 'id', '|');
			     }			      			  
			  }
		    });	 
	       
	   		      
    },
    
    failureCallBack : function(batch, options) {
      //TODO message error	     
	      alert('FAILURE!'); 
	      loadMask.hide();	      
	      this.loadTree('destination');	       	
    },   
    
 /*
  *  Panel Trees generation
  */
 
  init: function(config) {
    
		  if (config.baseId && config.baseId != 'root') 
				this.baseId = config.baseId;
	   
		  this.srcTree = this.initTree(this.configSrc);
		  this.destTree = this.initTree(this.configDest);
		  
// synchron load of destination tree if the corresponding  node exists		  
		  this.srcTree.on('itemexpand', function(node) { 		      
		      var root = this.destTree.getRootNode();
		      var destNode = root.findChild('id',node.get('id'),true);
		      if (destNode) destNode.expand();
		  },
		  this);
// toolbar		  
		  Ext.Array.each(this.basesNames, function(baseName,index){
			  var isTheBase = false;
			  if (this.baseId && baseName == this.baseId) var isTheBase = true;
			  this.bases[index] = {text: baseName,  toggleGroup: 'remoteBases', pressed: isTheBase, scope : this, toggleHandler: this.loadTrees}
		  }, this);
						    
		  var myConf = {
		   
		    id : 'rb_tab_panel', 
		    title : 'Remote Data Base',		   		  
		    items: [                 
			    this.srcTree, 
			    this.destTree                      
			  ],
		    tbar: this.bases,	                       
		    fbar: [
			      { text: 'Save Modifs', 
				scope : this,					  
				handler: function(){				  
				      var store = this.destTree.getStore();
				      
				       var removed = store.getRemovedRecords();
				       var updated = store.getUpdatedRecords();				        				  
			// if only removed: no sync - already removed at Server by node.delete	
			//TODO 	 is this condition OK??				        				       
					if (Ext.Array.union(removed,updated).length != removed.length) {  
						    loadMask.show();
						    store.sync({ success : this.successCallBack, failure: this.failureCallBack, scope : this});	
					}
				    }
				}				   
			  ],
		    listeners : {
				scope : this,
				destroy : function() { 	
				   if (this.hasModifs) {
				      // reload RemoteParam Tree in explorer
					var explorerTree = Ext.getCmp(amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
					if (explorerTree) {					  
					      var explorerTreeStore = explorerTree.getStore();
					      var explorerRoot = explorerTreeStore.getRootNode();
					      var explorerPath = '/root/parameters-treeBase/myRemoteData-treeRootNode/';
					      
					      explorerTreeStore.load( { node : explorerRoot, 
									params : { nodeType: 'resources'},
									callback : function(){
									  explorerTree.selectPath(explorerPath);						 
									}
					      });	      	 
				      }
				   }
				}
		    }
		};

		Ext.apply(this, Ext.apply(arguments, myConf));
 
    }	   		 	  
    
});