// JavaScript Document
// E2cs alpha 0.0.7
// Extjs-Event-Calendar Solution 
// task.js
// Author: Carlos Mendez
// --------------------------------------------------------------
// Tasks for Day view  ------------------------------------------
// --------------------------------------------------------------
//	27-Sep-2008
//	Minor fixes cause of bugs with element's ID's
// --------------------------------------------------------------
// 04-08-08
// Changes for display on opera 
// Xtemplate object added for Qtip format  
// --------------------------------------------------------------
// Note: this will not work on week view, the beheavior is different
// --------------------------------------------------------------

Ext.ECalendar.daytask = function(config){
	Ext.apply(this,config);
	Ext.ECalendar.daytask.superclass.constructor.call(this);
};
Ext.extend(Ext.ECalendar.daytask, Ext.util.Observable, { 
  previndex:0,
	createdelementno:0,
	editable:true, 
	parentview:null, 											//dayview object
	baseBody:null,   											//ext element already created  that contains the tasks in day view 
	datehandle:new Date(),  									//date to handle 
	showQtip:true,												//Show Qtips on tasks
	tasksOffset: 30, 	
	task_id:0,
	task_index:0,
	task_subject:'',		
	task_starts:'',
	task_ends:'',
	task_description:'', 
	task_clsOver:'', 
	task_increment:5,
	task_width:100, 											//base Task width 
	bgcolor:'#E0FFA2',			  								//base color
	task_format:'d-m-Y H:i:s a', 								//base format on Tasks (qtips) 
	moreMenuItems:[],											// Menu items  objects for custom actions 
	contextMenuLabels: e2cs.cal_locale.contextMenuLabelsDay,  	// Labels for  Base Menu items
	// added on 0.0.4 
	tplqTip: new Ext.XTemplate( '<tpl for=".">{starxl}{startval}<br>{endxl}{endval}<hr color="#003366" noshade>{details}</tpl>' ),
	ShowMenuItems:[1,1,1,1,1],  //0.0.11 ADD, DELETE, EDIT, NEXT day, PREV DAY 
	evenLaunch:'dblclick', 
	init: function(calendar,dayview){ 
		this.calx = calendar; 
		this.vday = dayview;
	},
	render:function(){
		var m_starttime =  this.calx.currentdate.format('m/d/Y ') + this.vday.startTime ; 
		var m_endtime =    this.calx.currentdate.format('m/d/Y ') + this.vday.endTime   ; 			
		this.totalhours =  this.calx.dateDiff(new Date(m_starttime),new Date(m_endtime),e2cs.dateParts.HOUR); 
		// check if the task hour is Ok 
		var inittimetask  = this.checkTasktime(this.task_starts); 
		var endtimetask   = this.checkTasktime(this.task_ends); 
		var checkbetwdate = this.calx.currentdate.between( new Date(m_starttime), new Date(m_endtime) ); 		
		//posicion inicial de la tarea 
		var diffstartinipos = this.calx.dateDiff( new Date(m_starttime), new Date(inittimetask),e2cs.dateParts.MINUTE); 
		if (diffstartinipos<0 ){
			initpos = 0; 
			flagstarttasttext = e2cs.cal_locale.task_LessDaysFromTask; // sample'(-)<br>'; 
		} else {
			initpos = diffstartinipos; 
			flagstarttasttext = ''; 
		}
		var diffendpos = this.calx.dateDiff(new Date(m_endtime), new Date(endtimetask),e2cs.dateParts.MINUTE); 
		if (diffendpos>0){ 
			endpos = (this.totalhours) * 60; //endpos = (this.totalhours + 1) * 60; 
			endpos = Math.abs(initpos - endpos); 
			flagendtasttext = e2cs.cal_locale.task_MoreDaysFromTask; // sample '<br>(+)'; 
	    } else { 
			var tmpdate = new Date(inittimetask); 
			var dtstartday =  new Date(  this.calx.currentdate.format('m/d/Y') + ' ' + this.vday.startTime ); 
			if  (tmpdate<dtstartday) { 
				endpos = this.calx.dateDiff( new Date(m_starttime), new Date(endtimetask) ,e2cs.dateParts.MINUTE); 
			}  else { 
				endpos = this.calx.dateDiff( new Date(inittimetask), new Date(endtimetask) ,e2cs.dateParts.MINUTE); 
			} 
			//if (endpos==(this.totalhours * 60) ) { endpos = endpos -76; }  0.0.4 bad behavior
			flagendtasttext = ''; 
		} 
		this.task_index = (this.vday.tasks.length); 
		this.taskobject = this.baseBody.createChild({ tag: 'div',	 cls: 'task',	html: flagstarttasttext + this.task_subject  + flagendtasttext });
		this.taskobject.dom.setAttribute('id', this.calx.id + '-ecaltask-' 	+  this.task_index + '');
		this.taskobject.dom.setAttribute('ec_id', '' 		+  this.task_id + '');
		this.taskobject.dom.setAttribute('ec_starts', '' 	+  inittimetask + '');
		this.taskobject.dom.setAttribute('ec_ends', '' 	 	+  endtimetask + '');
		this.taskobject.dom.setAttribute('ec_subject', '' 	+  this.task_subject + '');
		this.taskobject.dom.setAttribute('ec_cnt', '' 		+  this.task_description + '');
		this.taskobject.dom.setAttribute('ec_storeindex', ''+  this.task_index + '');
		this.taskobject.setStyle({top:'' + initpos + 'px' } );		
		this.taskobject.setStyle({height:'' + endpos + 'px' } );
		this.taskobject.setStyle({width :'' + this.task_width + 'px' } );
		if (this.tasksOffset=='auto'){ 
			if (this.task_index<=1){
				var anchoposx = 0; 
			}else{
				tmpoffset = this.task_width; 
				anchoposx= 0; //var anchoposx = Ext.get('ecaltask-' + (this.task_index-1)).getX() + tmpoffset;	
				for (var x=0;x<=(this.vday.tasks.length-1);x++){ 
					if (x!=0){ anchoposx+= Ext.get(this.calx.id + '-ecaltask-' + (x)).getWidth(false);	}
				}
			} 
		} else {  //is number 
			if (this.task_index<=1){
				var anchoposx = 0;
			} else { 
				tmpoffset = this.tasksOffset; //var anchoposx = Ext.get('ecaltask-' + (this.task_index-1)).getX() + tmpoffset;		
			} 
		} 
		//this.taskobject.setX(this.baseBody.getX() + anchoposx);
		newancho=0; 
		for (var x=0;x<=(this.vday.tasks.length);x++){ 
			if (x!=0){	newancho+= Ext.get(this.calx.id + '-ecaltask-' + (x)).getWidth(false);	}
		}
		if (  newancho >this.baseBody.getWidth(false) ){ 
			Ext.get(this.calx.id + '-daybody').setWidth(newancho); 
			Ext.get('tdbaseday').setWidth(newancho); 
			//Ext.get('tableallday').getWidth(false); 
			//Ext.get('tdbaseday').setWidth(this.taskobject.getX() + this.taskobject.getWidth(false) ); 
		    //Ext.get('daybody'); 
			//this.baseBody.setWidth( this.taskobject.getX() + this.taskobject.getWidth(false) ); 
		}
		if (Ext.isOpera) { 	/*fix for Opera 9x	*/	} else { this.taskobject.setX(this.baseBody.getX() + anchoposx);} 
		this.taskobject.setY(this.baseBody.getY() + initpos); // fix for moredays task and normal tasks		
		if (this.bgcolor){ 
			this.taskobject.setStyle('background-color' ,'' + this.bgcolor + ''); 
		} else { 
			this.taskobject.setStyle('background-color' ,'#99CC99'); 
		} 
		if(Ext.isIE){ // bug fix for IE6 didnt show taks cause they ewent at the bottom and also the base day element its at the top  :(  weird IE stuff 
			this.taskobject.setStyle('z-index' ,'2000'); 
		}else{
			this.taskobject.setStyle('z-index' ,'auto');
		}
		if (this.showQtip){ 
			var tmpdate = new Date(inittimetask);  			
			var startlabel = tmpdate.format(this.task_format); 
				tmpdate = new Date(endtimetask);            
			var endlabel =   tmpdate.format(this.task_format); 
			this.taskobject.dom.qtitle= this.task_subject;		
			// 0.0.4 new feature Qtip template 		
			var datatip = {starxl:   e2cs.cal_locale.task_qtip_starts,
						   startval: startlabel,
						   endxl:    e2cs.cal_locale.task_qtip_ends, 
						   endval:   endlabel,
						   details:  this.task_description};
			//this.taskobject.dom.qtip  = e2cs.cal_locale.task_qtip_starts + startlabel + "<br>" + e2cs.cal_locale.task_qtip_ends + endlabel + '<br>' + this.task_description ; 
			this.taskobject.dom.qtip = this.tplqTip.apply(datatip);
//			tplqTip: new Ext.XTemplate( 
//				'<tpl for=".">{starxl}:{startval}<br>{endxl}:{endval}<hr color="#003366" noshade>{details}</tpl>'
//		    ),			
		}
		//0.0.11 task_clsOver implemented
		if (this.task_clsOver!=''){ this.taskobject.addClassOnOver(this.task_clsOver); }
		//0.0.11 changed so you can decide wheter click or dobleclick or nothing for the task object 
		//this.taskobject.addListener('dblclick', this.onDblclick, this );
		this.taskobject.addListener(this.evenLaunch, this.onDblclick, this );		
		if (Ext.isOpera){ 
				this.taskobject.addListener('mousedown',this.operabuttons,this); 
		} else { 
				this.taskobject.addListener('contextmenu', 
						this.oncontextmenu, this, {
							   stopPropagation:true,
							   normalized :true,
							   preventDefault:true
				} );
		} 
		if (initpos==0 && endpos>=(this.totalhours * 60)) { // no resizable cause its all day task or more :P
		}  else { //here comes the trouble :P 
			if (this.editable){ 
				if (flagendtasttext==''){ 
					var snap = new Ext.Resizable(this.calx.id + '-ecaltask-' + this.task_index + '', {
						pinned:false,
						width:this.task_width,
						handles: 's',
						heightIncrement:this.task_increment,
						minHeight: 15,
						maxHeight: ((this.totalhours * 60) - initpos),
						dynamic: true,
						draggable : false
					});
					var tmpbody = this.baseBody; 						
					var tmpvday = this.vday;
					var tmptask = this;    			
					var tmpcalendar = this.calx;
					snap.on({
						'resize':{
							fn: function( objthis, width, height, evtObj){ 
								var datatask = tmptask.getTaskarray(objthis.el); 
								var check = tmpcalendar.fireEvent("beforeTaskMove", datatask, tmptask, tmpvday, tmpcalendar);
								if (!check){ // calc new position for - start time and end time  and updates Task's tags 
									tmptask.applyChange(objthis.el);  
									var newdatatask= tmptask.getTaskarray(objthis.el);  //with updates 
									tmpcalendar.fireEvent("TaskMoved", newdatatask, tmptask, tmpvday, null);// afterChange fires
								} 
							} 
							, scope:this	
						}
					}) ; 
					// if it has moredays (+) or (-) then drag does not apply
					if (flagstarttasttext=='' && flagendtasttext == ''){  
								var taskdrag  = new Ext.dd.DDProxy(this.calx.id + '-ecaltask-' + this.task_index + '','task-group',{xTicks : 0,	yTicks : 5});	
								// needed this vars cause in the endrag this i cant change it  :( 
								var tmpbody = this.baseBody; 	
								var tmpvday = this.vday;
								var tmptask = this;    			
								var tmpcalendar = this.calx;
								// --------------------------------------------------------------------
								taskdrag.startDrag = function(){
									  this.constrainTo( tmpbody.id );
									  this.setXConstraint(0,0,0); 
									  var dragEl = Ext.get(this.getDragEl());
									  var el = Ext.get(this.getEl());
									  dragEl.applyStyles({border:'','z-index':2000});
									  dragEl.update(el.dom.innerHTML);
									  dragEl.addClass('task-drag' + ' dd-proxy');		  
								};
								taskdrag.endDrag = function(){
										var dragEl = Ext.get(this.getDragEl());
										var el = Ext.get(this.getEl());
										var datatask = tmptask.getTaskarray(this.id); 
										// fire event before taskchange
										var check = tmpcalendar.fireEvent("beforeTaskMove", datatask, tmptask, tmpvday,tmpcalendar); 
										if (!check){ 
											el.setY(dragEl.getY()); // x never changes 
											tmptask.applyChange(this);  // calc new position for - start time and end time  and updates Task's tags 
											var newdatatask= tmptask.getTaskarray(this.id);  //with updates 
											// afterChange fires
											tmpcalendar.fireEvent("TaskMoved", newdatatask, tmptask, tmpvday,this); 
										} else { 
											// restore normal postion if canceled
											// cause nothing is done to update the element 
											//  to restore normal postion if canceled (beta)
											//	tmptask.resetChange(this);  
											//	** optional function no implementation yet 
										} 	
								};
					} 
				} 
			} 
		} 
	},
	operabuttons: function (evx,elx,obx){//alert ("boton:" + evx.button); 
			if (Ext.isOpera){ if (evx.button==2){ this.oncontextmenu(evx,elx,obx); }  
		}
	}, 
	oncontextmenu: function (evx,elx,obx){
		if (Ext.isOpera){ if (evx.button!=2){ return false; } }
		if (this.ShowMenuItems[0]!=true && this.ShowMenuItems[1]!=true && this.ShowMenuItems[2]!=true && this.ShowMenuItems[3]!=true  && this.ShowMenuItems[4]!=true && this.moreMenuItems.length<=0){ return false; }
		evx.stopEvent();		
		var tmpdata= Ext.get(elx.id);
			if (this.menu){ this.menu.removeAll();	}
		this.menu = new Ext.menu.Menu({
			shadow: true, 
			items:[{id: 'day_ctxbtn_task-add',		iconCls:'x-calendar-day-btnmv_add',		text: this.contextMenuLabels.taskAdd, 	scope:this},
				   {id: 'month_ctxbtn_task-delete', iconCls: 'x-calendar-day-btnmv_delete',	text: this.contextMenuLabels.taskDelete,scope:this},
				   '-',
				   {id:'month_ctxbtn_task-edit',	iconCls: 'x-calendar-day-btnmv_task',	text: this.contextMenuLabels.taskEdit + tmpdata.getAttributeNS('tag','ec_subject'),		scope:this	},
				   '-',
				   {id:'month_ctxbtn_task-go-nd', 	iconCls: 'x-calendar-day-btnmv_nextday',text: this.contextMenuLabels.NextDay,	 scope:this},
				   {id:'month_ctxbtn_task-go-pd', 	iconCls: 'x-calendar-day-btnmv_prevday',text: this.contextMenuLabels.PreviousDay,scope:this}
			]
		});
		if (this.vday.moreMenuItems.length>0) { 
			this.menu.add('-'); 
			for (var i=0; i<this.vday.moreMenuItems.length; i++){
				// var idmenuitem = this.moreMenuItems[i].id;  0.0.4 bug in custom action sending the id the problem was the last id was returned always
				this.moreMenuItems[i].rendered =false; 
				this.moreMenuItems[i].addListener('click', 
							function(parx,parz){ 
									this.onCustomMenuAction(parx.id,Ext.get(elx),this ); //this.onCustomMenuAction( idmenuitem , Ext.get(elx), this ); 0.0.4 bug 
							}, this); 
				this.menu.add( this.moreMenuItems[i]);
			}
		} 
		this.menu.items.items[0].addListener('click', function(){ this.onActionTask( 1, Ext.get(elx), this ); 	}, this); 
		this.menu.items.items[1].addListener('click', function(){ this.onActionTask( 2, Ext.get(elx), this ); 	}, this); 
		this.menu.items.items[3].addListener('click', function(){ this.onActionTask( 3, Ext.get(elx), this ); 	}, this); 		
		this.menu.items.items[5].addListener('click', function(){ this.vday.onclicknext_day(); }, this);  //next day		
		this.menu.items.items[6].addListener('click', function(){ this.vday.onclickprev_day(); }, this);  //prev day	
		//0.0.11 - check visibility on the menu-items according to the new property 
		//ShowMenuItems:[1,1,1,1,1],  //0.0.11 ADD, DELETE, EDIT, NEXT day, PREV DAY
		if (this.ShowMenuItems[0]!=true){this.menu.items.items[0].hidden=true; } 
		if (this.ShowMenuItems[1]!=true){this.menu.items.items[1].hidden=true; } 
		if (this.ShowMenuItems[0]!=true && this.ShowMenuItems[1]!=true){this.menu.items.items[2].hidden=true; } //sep
		if (this.ShowMenuItems[2]!=true){ this.menu.items.items[3].hidden=true; this.menu.items.items[4].hidden=true;} 
		if (this.ShowMenuItems[3]!=true){this.menu.items.items[5].hidden=true; } 
		if (this.ShowMenuItems[4]!=true){this.menu.items.items[6].hidden=true; } 
		if (this.vday.moreMenuItems.length>0) { 
			if (this.ShowMenuItems[3]!=true && this.ShowMenuItems[4]!=true){
				this.menu.items.items[7].hidden=true; 
			}
		} 
		//--------------------------------------------------------------------------
		this.menu.on('hide', this.onContextTaskMenuHide, this);
		this.menu.showAt(evx.xy);
	}, 
	onCustomMenuAction: function(MenuId,taskEl,TaskObj){
		var datatask = this.getTaskarray(taskEl); 
		this.calx.fireEvent("customMenuAction", MenuId,'day',datatask,taskEl, this.vday); 
	},
	// private use 
	applyChange: function (TaskEl){
		//recalcs position and Start time and End time  if its from the same date also calcs the new position
		var m_starttime =  this.calx.currentdate.format('m/d/Y ') + this.vday.startTime; 
		var m_endtime =    this.calx.currentdate.format('m/d/Y ') + this.vday.endTime; 			
		var tmpEl =  Ext.get(TaskEl.id); 
		var newposstart =  Math.abs(   tmpEl.getTop() - Ext.get(this.baseBody).getY() ); 
		var newposend   = tmpEl.getHeight(); 
		var newdateTaskstart = new Date(m_starttime).add(Date.MINUTE,newposstart); 
		var newdateTaskEnds  = newdateTaskstart.add(Date.MINUTE,newposend);
		//universal format for dates (in this control)		
		tmpEl.dom.setAttribute('ec_starts', '' 	+  newdateTaskstart.format('m/d/Y H:i:s a') + '');  
		tmpEl.dom.setAttribute('ec_ends'  , '' 	+  newdateTaskEnds.format('m/d/Y H:i:s a')  + '');
		if (this.showQtip){ 		
			var startlabel = newdateTaskstart.format(this.task_format);            
			var endlabel =   newdateTaskEnds.format(this.task_format); 
			//tmpEl.dom.qtitle= this.task_subject;
			tmpEl.dom.qtip  = e2cs.cal_locale.task_qtip_starts + startlabel + "<br>" + e2cs.cal_locale.task_qtip_ends + endlabel + '<br>' + this.task_description ; 
		} 		
	},
	onActionTask: function (action, taskEl, TaskObj ){
		var datatask = this.getTaskarray(taskEl); 
		switch(action){
			case 1:  //add				
				this.calx.fireEvent("taskAdd",this.calx.currentdate);	
				break; 
			case 2: // delete
				var check = this.calx.fireEvent("beforeTaskDelete", datatask,this.vday );  
				if (check!=true){ 
					if (this.calx.fireEvent("onTaskDelete",datatask)==true){ 
						this.calx.fireEvent("afterTaskDelete",datatask,true);
					} else { 
						this.calx.fireEvent("afterTaskDelete",null,false);
					} 
				} 
				break; 
			case 3: //edit
				var check = this.calx.fireEvent("beforeTaskEdit",datatask,this.vday);  
				if (check!=true){ 
					// 0.0.4  - code still missing
					if (this.calx.fireEvent("onTaskEdit",datatask)==true){ 
						this.calx.fireEvent("afterTaskEdit",datatask,true);
					} else { 
						this.calx.fireEvent("afterTaskEdit",null,false);
					}	
				}
				break; 			
			default: 
				break; 
		} 
	},
	onContextTaskMenuHide: function (){ /* nothing happens :( */ },
	onDblclick: function(evx,elx,obx){
		var tmpdata= Ext.get(elx.id);
		var datatask = this.getTaskarray(elx); 
		this.calx.fireEvent("taskDblClick",datatask,this.vday,this.calx,'day');
	},
	getTaskarray: function(TaskElx){ 
		var tmpdata= Ext.get(TaskElx);
		var datatask =[]; 
		datatask[0]=tmpdata.getAttributeNS('tag','id') ; 
		datatask[1]=tmpdata.getAttributeNS('tag','ec_id') ; 		
		datatask[2]=tmpdata.getAttributeNS('tag','ec_subject') ; 
		datatask[3]=tmpdata.getAttributeNS('tag','ec_starts') ; 
		datatask[4]=tmpdata.getAttributeNS('tag','ec_ends') ; 		
		datatask[5]=tmpdata.getAttributeNS('tag','ec_cnt') ; 
		datatask[6]=tmpdata.getAttributeNS('tag','ec_storeindex') ; 
		return 	datatask; 	
	},
	checkTasktime: function(taskvalue) { 
		var test = taskvalue.indexOf(":", 0); 
		if (test<=0){
			taskvaluefix = taskvalue + ' ' + this.vday.startTime; 
		} else { 
			taskvaluefix = taskvalue ; 
		}
		return taskvaluefix ; 
	}

}); 