/**
 * Project   : AMDA-NG
 * Name      : SearchUI.js
 * @class 	 amdaUI.SearchUI
 * @extends      Ext.container.Container 
 * @brief    Search Module UI definition (View)
 * @author CDA
 * @version $Id: SearchUI.js 2467 2014-07-10 16:06:26Z myriam $  
 */

Ext.define('amdaUI.SearchUI', {
	extend: 'Ext.container.Container',
	alias: 'widget.panelSearch',
	
	requires: [
	 	'amdaUI.CalculatorUI',
	 	'amdaUI.TimeSelectorUI',
	 	'extensions.SelectableTextArea',
		'amdaUI.SearchParamEditorPlugin'	 		
	],    
 
	constructor: function(config) {	
          
	this.init(config);
	this.callParent(arguments);	
        // load object into view    
	 this.loadObject();
	},

	addTT : function(newTTName,newTTid){
	this.timeSelector.addTT(newTTName,newTTid);
	},
	
        addTTs : function(TTarray) {
        // set TTTab	    
            this.timeSelector.setTTTab(TTarray);
        },
               
        addParam : function(newParamName, isLeaf) {
            if (isLeaf){
                var selection = this.constructionField.getSelection();
                this.constructionField.setValue(selection.beforeText + newParamName + selection.afterText);
                this.constructionField.focus();
                this.constructionField.setCaretPosition(this.constructionField.getValue().length);  
            }
        },
        
       /**
         * Set Start-Stop from parameter info (Local & MyData)
         */ 
        setTimeFromData : function(obj) {
                                                                  
            var dateStart = new Date(obj.start.replace(/[T|Z]/g,' ').replace(/\-/g,'\/')); 
            var dateStop = new Date(obj.stop.replace(/[T|Z]/g,' ').replace(/\-/g,'\/')); 
            
            this.down('form').getForm().setValues({ startDate : dateStart, stopDate : dateStop });
        },
        
        setObject : function(obj) {             
            this.object = obj;  
            this.loadObject();
        },
	
	/**
	 * update this.object from form
	 */
	updateObject : function(){    
	// get the basic form
	var basicForm = this.formPanel.getForm();
	// get the timeSource selected
	var timeSource = this.timeSelector.getActiveTimeSource();	    
	var updateStatus = true;

	  var fieldsWithoutName = basicForm.getFields().items;
	  Ext.Array.each(fieldsWithoutName, function(item, index,allItems){
	      if(item !== this.fieldName) { 		     
		   if (!item.isValid()) {
    		  if ((timeSource === amdaModel.AmdaTimeObject.inputTimeSrc[0]) &&
       			   ((item.name == 'startDate') || (item.name == 'stopDate') || (item.name == 'duration'))) {
       			  	updateStatus = true;
       		  }
       		  else {
       			// set update isn't allowed
                     updateStatus = false;
                     return false;
       		  }       
		   }
	      }
	  }, this);

	  if (timeSource === amdaModel.AmdaTimeObject.inputTimeSrc[0] // timeSource  'TimeTable'
		    && this.timeSelector.TTGrid.getStore().count() == 0) {

		  Ext.Msg.show({
		      title: 'Warning', msg: 'You chose Time Selection `by TimeTable` but no timeTable was added!'
			  +'<br>You must add one or choose Time Selection `by Interval`', 
		      icon: Ext.MessageBox.WARNING, buttons: Ext.Msg.OK
		  }); 
		  updateStatus = false;    
	  }
	  // if the update is allowed
	  if (updateStatus) {
	  /// real object update
	  // update TimeTable object with the content of form
	    basicForm.updateRecord(this.object);
	    this.object.set('timesrc', timeSource);
	    // set valid intervals into TimeTable object
	    if (timeSource === amdaModel.AmdaTimeObject.inputTimeSrc[0]) {	      
		  this.object.set('timeTables',this.timeSelector.TTGrid.getStore().data.items);
	    }
	  }    
	  // return the update status
        return updateStatus;	    
	},
	
	/**
	 * load this.object into form
	 */
	loadObject : function(){
	// load object into form
	 
	this.formPanel.getForm().loadRecord(this.object);       
        // set object's TTs into the timeselector
	this.addTTs(this.object.get('timeTables'));	 
	},
	
	/**
	 * save method called by Save button to launch the save process
	 */
	saveProcess : function(toRename){
	 // if the TimeTable object has been modified	  
        if (this.object.dirty) {            
            // TT module
            var searchModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.search.id);//('search-win');           
            // if the name has been modified this is a creation
            if (this.object.isModified('name')){
                
                // if object already has an id : it's a 'rename' of an existing Condition
                if (this.object.get('id')){
                    // the context Node is the parent node of current edited one
                    var contextNode = searchModule.linkedNode.parentNode;
                    // link a new node to the TimeTableModule
                    searchModule.createLinkedNode();
                    // set the contextNode
                    searchModule.linkedNode.set('contextNode',contextNode);
                    // create a new object linked
                    searchModule.createObject(this.object.getJsonValues());            
                    var searchObj = searchModule.linkedNode.get('object');                           
                    // synchronisation of objects		     
                    this.object = searchObj; 		      
		    if (toRename) searchModule.linkedNode.toRename = true;
                }               
                // fire creation event
              //  this.object.fireEvent('create');
                searchModule.linkedNode.create();
            } else {           
                searchModule.linkedNode.set('contextNode',searchModule.contextNode); 
                // this.object.fireEvent('modify');
		searchModule.linkedNode.update();
            }
          }
	},
	
	/**
	 * overwrite metod called by Save button
	 */
	overwriteProcess : function(btn){	
	if (btn == 'cancel') return;	
           
        this.fieldName.clearInvalid();    
	this.saveProcess(true);		
	},
	
	/**
	 * search method called by 'Do Search' button to launch the search process
	 */
	doSearch : function(){	     
	var searchModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.search.id);
	searchModule.linkedNode.execute();
	   // fire execution  
	  //  this.object.fireEvent('execute',this.object.dirty);
	},
        
 /**
  *   Check if brackets are balanced
  */        
        isBalanced : function(str){ 
         str =  (""+str).replace(/[^()\[\]{}]/g, ""); 
         var bracket = {
                    "]": "[",
                    "}": "{",
                    ")": "("
                },
                openBrackets = [], 
                isClean = true,
                i = 0,
                len = str.length;

            for(; isClean && i<len; i++ ){                
                if( bracket[ str[ i ] ] ){
                    isClean = ( openBrackets.pop() === bracket[ str[ i ] ] );
                }else{
                    openBrackets.push(str[i]);
                }
            }
            if (!(isClean && !openBrackets.length)) return 'Brackets are not balanced';
           
            return true; 
        },
        
        /**
         * Update constructionField (Search Condition) in window search        
         */     
        updateConstruct : function(oldval,newval) 
        {
            var expression = this.constructionField.value;
            oldval = oldval.replace(/[(]/g,"\\(");
            oldval = oldval.replace(/[)]/g,"\\)");	
            var reg=new RegExp(oldval, "g");
            expression = expression.replace(reg, newval);
            this.constructionField.setValue(expression);
	},

	/**
	 * Check if changes were made before closing window 
	 * @return true if changes
	 */	   
	fclose : function() {
                var form = this.formPanel.getForm();
		var isDirty = form.isDirty();
		return isDirty;
	},
	
        /**
         *  Component configiration / init
         */
        init : function(config)	
        {	  
            this.timeSelector = new amdaUI.TimeSelectorUI({id: 'SearchTimeSelector',flex: 2});

            this.fieldName = new Ext.form.field.Text({
                labelAlign: 'top', itemId: 'formParamName',
                fieldLabel: 'Request Name<b>*</b>',
                name : 'name',
                width: 375,
                colspan: 3,
                allowBlank : false,
                stripCharsRe: /(^\s+|\s+$)/g,
                validateOnChange: false,
                validateOnBlur: false,
                validFlag: false,
	            validator : function() {
	            	return this.validFlag;
	            }
            });

            this.constructionField = new extensions.SelectableTextArea({
                labelAlign: 'top',
                itemId: 'formSearchCondition',
                fieldLabel:'Data Mining Condition<b>*</b>',
                allowBlank : false, blankText : 'Condition expression is required',
                name: 'expression',
                validateOnChange: false,
                validateOnBlur: false,
                validator : this.isBalanced,
                flex : 2.5,
                listeners :
                    {
                        render : function(o,op)
                        {
                            var me = this;
                            var el = me.bodyEl;
                            var dropTarget = Ext.create('Ext.dd.DropTarget', el, {
                                ddGroup: 'explorerTree',
                                notifyEnter : function(ddSource, e, data) 
                                { },
                                notifyOver  : function(ddSource, e, data)
                                { 
                                    if (data.records[0].data.nodeType == 'localParam' && data.records[0].get('notyet')) {
                                        this.valid = false;
                                        return this.dropNotAllowed;   
                                    }
                                    if (((data.records[0].data.nodeType == 'localParam')   ||
                                            (data.records[0].data.nodeType == 'remoteParam') || 
                                            (data.records[0].data.nodeType == 'remoteSimuParam') ||
                                            (data.records[0].data.nodeType == 'derivedParam') ||
                                            (data.records[0].data.nodeType == 'myDataParam') ||
                                            (data.records[0].data.nodeType == 'alias'))&&
                                            (data.records[0].data.leaf) &&
                                            !data.records[0].data.disable)
                                        {
                                            this.valid = true;
                                            return this.dropAllowed;
                                        }
                                        this.valid = false;
                                        return this.dropNotAllowed;
                                },
                                notifyDrop  : function(ddSource, e, data)
                                {
                                    if (!this.valid) return false;
                                                        
                                    var nameToSent;
                                    switch (data.records[0].get('nodeType'))
                                    {
                                    case 'localParam' :
                                    case 'remoteParam' :
                                    case 'remoteSimuParam' :    
                                        nameToSent = data.records[0].get('id');
                                        if (data.records[0].get('alias')!= "" )
                                            var nameToSent = "#"+data.records[0].get('alias');
                                        break;
                                    case 'alias' :
                                        nameToSent = "#"+data.records[0].get('text');
                                        break;
                                    case 'derivedParam' :
                                        nameToSent = "ws_"+data.records[0].get('text');
                                        break;
                                    case 'myDataParam' :
                                        var name = data.records[0].get('text');
                                        nameToSent = "wsd_"+name;
                                        var size = data.records[0].get('size');
                                        if (size &&  size > 1) {
                                            nameToSent += "(0)";
                                            myDesktopApp.warningMsg("parameter "+name+" is array of size: "+size+"<br/>Please put index");
                                        }
                                        break;
                                    default :
                                        return false;
                                    }
                                    var searchModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.search.id);
                                    if (data.records[0].get('needsArgs')) { 
                                        searchModule.getUiContent().fireEvent('openParamEditor',nameToSent);
                                    } 
                                    else {
                                        searchModule.addParam(nameToSent,true);	
                                    }
                                    return true;
                                }
                            });
                        }
                    }
            });

            this.formPanel = new Ext.form.Panel({
                region : 'center',  
                bodyStyle: { background : '#dfe8f6' },  
                border: false, buttonAlign: 'left',
                trackResetOnLoad: true,  //reset to the last loaded record
                layout : { 
                            type : 'vbox',
                            align: 'stretch',
                            defaultMargins : { top:15, bottom:0, left: 15, right:15}
                },
                id: 'formSearch',
                defaults: {
                    border: false
                },
                items : [
                    { 
                        xtype: 'container',
                        flex: 2.5,
                        layout: {
                            type: 'hbox',  
                            align: 'stretch'
                        },
                        items: [
                                {
                                flex: 3,
                                xtype: 'container',
                                border: false,
                                layout: {
                                    type: 'table',
                                    columns: 3
                                },
                                defaultType: 'textfield',
                                defaults: {
                                        labelAlign: 'top'
                                },
                                items: [   
                                    this.fieldName,
                                    {
                                            xtype :'displayfield', width: 165,
                                            hideLabel: true, 
                                            value: '<b>Averaging/Interpolation</b>'
                                    },
                                    { xtype: 'component', width: 45 },
                                    {
                                        xtype :'displayfield', width: 165,
                                        hideLabel: true, 
                                        value: '<b>Data Gap</b>'
                                    },
                                    {
                                        xtype: 'numberfield', name: 'sampling',
                                        fieldLabel: 'Sampling Time Step (sec)*', minValue : 0,
                                        labelAlign: 'top', hideTrigger: true, width: 165
                                    },
                                    { xtype: 'component', width: 45 },
                                    {
                                        xtype: 'numberfield',  name: 'gap',
                                        fieldLabel: 'if no data for interval', minValue : 1,
                                        labelAlign: 'top', hideTrigger : true, width: 165
                                    },
                                    {
                                        xtype: 'textfield',
                                        name: 'description', 
                                        xtype: 'textarea', fieldLabel:'Description',
                                        width: 375, height: 70,
                                        colspan: 3
                                    }]	
                                },   
                            this.timeSelector
                        ]
                    },
                    this.constructionField
                ],
                fbar: [
                    {
                        text: 'Do Search',
                        scope : this,
                        handler: function(button){
                            // update object with user's values
                            // if the return is true (object had been updated)
                            if(this.updateObject()){
                                // launch the search process                           
                                this.doSearch();			   			 
                            }
                        }
                    },
                    {
                        text: 'Save Request',
                        scope: this,
                        handler: function(){
                            // update object with user's values 
                            // if the return is true (object had been updated)
                            if (this.updateObject()){
                            	var searchModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.search.id);	
                            	if (!searchModule)
                            		return;
                            	var me = this;
                            	
                            	searchModule.linkedNode.isValidName(this.fieldName.getValue(), function (res) {
                            		if (!res)
                            		{
                            			me.fieldName.validFlag = 'Error during object validation';
                            			myDesktopApp.errorMsg(me.fieldName.validFlag);
                            			me.fieldName.validate();
                            			return;
                            		}
  								  
                            		if (!res.valid)
                            		{
                            			if (res.error)
                            			{
                            				if (res.error.search('subtree') != -1) {  							
                            					Ext.MessageBox.show({title:'Warning', 
                            						msg: res.error+'<br/>Do you want to overwrite it?',
                            						width: 300,
                            						buttons: Ext.MessageBox.OKCANCEL, 
                            						fn : me.overwriteProcess,
                            						icon: Ext.MessageBox.WARNING,
                            						scope : me
                            					});
                            					me.fieldName.validFlag = true;
                            				}
                            				else
                            					me.fieldName.validFlag = res.error;
                            			}
                            			else
                            			{
                            				me.fieldName.validFlag = 'Invalid object name';
                            				myDesktopApp.errorMsg(me.fieldName.validFlag);
                            			}
                            			me.fieldName.validate();
                            			return;
                            		}
  								  
                            		me.fieldName.validFlag = true;
                            		me.fieldName.validate();
                            		me.saveProcess(false);
                            	});  
                            }                              
                        }
                    },
                    {
                        text: 'Reset',
                        scope : this,
                        handler: function(){
                            var searchModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.search.id);			
                            searchModule.createLinkedNode();
                            searchModule.createObject();
                            this.setObject(searchModule.getLinkedNode().get('object'));                           
                        }
                    }
                ] 
            });		
                
            var myConf = {
                layout: 'border',
                defaults: { layout: 'fit', border: false },
                items: [
                    this.formPanel,                         
                    {
                        xtype: 'panel', region: 'south',
                        title: 'Information',
                        collapsible: true,
                        height: 100,
                        autoHide: false,
                        iconCls: 'icon-information',
                        bodyStyle: 'padding:5px',
                        loader: {
                            autoLoad: true,
                            url: helpDir+'dataMiningHOWTO'
                        }				 
                    }  
                ],
                plugins: [ {ptype: 'calculator', myBtns:[], context: 'Condition'}, {ptype: 'searchParamEditorPlugin'}]
            };

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