/* File: base/script/tj_admin_pagemanager.js





*/

Ext.namespace('TJ.Admin.LM');


/* Page Manager Components */


TJ.Admin.LM.setXtype = function(info){
			if(info.xtype)
				return info.xtype;
			if (info.serverType=='cl_pm_row')
				return 'tjadmin_pm_row';
			if (info.serverType=='cl_pm_column')
				return 'tjadmin_pm_column';
			return 'tjadmin_pm_cell';

		};



TJ.Admin.LM.initDragZone = function(panel) {

	panel.dragZone = new Ext.dd.DragZone(panel.body, {

		ddGroup:'PMDDGroup',
//      On receipt of a mousedown event, see if it is within a draggable element.
//      Return a drag data object if so. The data object can contain arbitrary application
//      data, but it should also contain a DOM element in the ddel property to provide
//      a proxy to drag.
        getDragData: function(e) {
//			return false;
			var sourceEl= e.getTarget('.pm-dragsource',10,true);

			if(sourceEl) {
				sourceCmp=Ext.getCmp(sourceEl.id);

					proxyEl = sourceEl.child(sourceCmp.proxySelector,false);
					d= proxyEl.dom.cloneNode(true);
					d.id=Ext.id();
					Ext.fly(d).setWidth(proxyEl.getWidth());
					return {
						copy:e.ctrlKey,
						sourceCmp: sourceCmp,
						repairXY: proxyEl.getXY(),
						ddel: d
					};
				
			}

        },

//      Provide coordinates for the proxy to slide back to on failed drag.
//      This is the original XY coordinates of the draggable element.
        getRepairXY: function() {
            return this.dragData.repairXY;
        }
    });
};



TJ.Admin.LM.initDropZone = function(panel){
	Ext.dd.ScrollManager.register(panel.body);
	
    panel.dropZone = new Ext.dd.DropZone(panel.body, {
			ddGroup:'PMDDGroup',
//      If the mouse is over a target node, return that node. This is
//      provided as the "target" parameter in all "onNodeXXXX" node event handling functions
        getTargetFromEvent: function(e) {
            return e.getTarget('.pm-dropsource');
        },
//      On entry into a target node, setup data for node over.
        onNodeEnter : function(target, dd, e, data){ 


			// setup this information for use in onNodeOver
			this.targetCmp=Ext.getCmp(target.id);
			if(this.targetCmp)
				this.targetOwnerCmp =this.targetCmp.ownerCt;
			if(this.targetOwnerCmp)
				this.targetIndex=this.targetOwnerCmp.items.indexOf(this.targetCmp);
	    },

//      On exit from a target node, unhighlight that node.
        onNodeOut : function(target, dd, e, data){ 
			if(this.targetCmp.xtype=='tjadmin_pm_main'){
				if(this.targetCmp.items && this.targetCmp.items.length)
				{
					this.targetCmp.items.last().getEl().removeClass('panel-insert-below');
				}
			}
			this.targetCmp.body.removeClass(['panel-insert-below','panel-insert-above','panel-insert-right']);
            Ext.fly(target).removeClass(['panel-insert-above','panel-insert-below','panel-insert-left','panel-insert-right']);
        },

//      While over a target node, return the default drop allowed class which
//      places a "tick" icon into the drag proxy.
		
		setVerticalDropIndex: function(e,targetEl,insert){
					if(e.getPageY() < targetEl.getY() + 15) {
						this.dropIndex=this.targetIndex;
						return true;
					} 
					if(e.getPageY() > targetEl.getY() + targetEl.getHeight() - 15){
						this.dropIndex=this.targetIndex+1;
						return true;
					}
					if(insert) {
						this.dropIndex=-1;
						return true;
					}
					return false;
		},
		setHorizontalDropIndex: function(e,targetEl){
					if(e.getPageX() < targetEl.getX() + 20) {
						this.dropIndex=this.targetIndex;
						return true;
					} 
					if(e.getPageX() > targetEl.getX() + targetEl.getWidth() - 20){
						this.dropIndex=this.targetIndex+1;
						return true;
					}
					return false;
		},

		checkCanDrop: function(targetEl,dd,e,data){



			// setup tree node values if they don't exist.
			if(! data.sourceCmp){
				data.sourceCmp=this.getSourceCmpFromNode(data.node);
			}
	//		console.log('data',data,data.sourceCmp.xtype);

			if (data.sourceCmp.xtype=='tjadmin_pm_column')  // Columns drop on cols or rows.  Doneski.
			{
				if(this.targetCmp.xtype=='tjadmin_pm_column'){
					if(! this.setHorizontalDropIndex(e,targetEl))
						return false;
					if( (data.sourceCmp.ownerCt == this.targetOwnerCmp)&& (!data.copy) || (this.targetOwnerCmp.canAddColumn())) // Same owner or there is room.
						return true;
					return false;
				}
				if(this.targetCmp.xtype=='tjadmin_pm_row'){
//					console.log('col on row');
					if(this.targetCmp.canAddColumn()) {
						this.dropIndex=-1;
						return true;
					}
				}
				return false;
			}

			// Boxes can be put above or below Cells/Rows
			// Boxes can be app

			// Cells can be put above or below other Cells/Rows
			// Cells can be appended to Columns and Main
			// Cells can be above below appended to Boxes

			
			if ((data.sourceCmp.xtype=='tjadmin_pm_cell')||(data.sourceCmp.xtype=='tjadmin_pm_box')) {
				if(this.targetCmp.xtype=='tjadmin_pm_cell' || this.targetCmp.xtype=='tjadmin_pm_row') {
					if(! this.setVerticalDropIndex(e,targetEl))
						return false;
					return true;
				}
				if(this.targetCmp.xtype=='tjadmin_pm_box'){
					if(! this.setVerticalDropIndex(e,targetEl,true))// allow insert as well!!!
						return false;
					return true;
				}

				if(this.targetCmp.xtype=='tjadmin_pm_column' || this.targetCmp.xtype=='tjadmin_pm_main') {
					this.dropIndex=-1;
					return true;
				}
					
				return false;
			}
			if(data.sourceCmp.xtype=='tjadmin_pm_row'){
				if(this.targetCmp.xtype=='tjadmin_pm_row') {
					if(! this.setVerticalDropIndex(e,targetEl))
						return false;
					return true;
				}
				if(this.targetCmp.xtype=='tjadmin_pm_column' || this.targetCmp.xtype=='tjadmin_pm_main') {
					this.dropIndex=-1;
					return true;
				}
				if(this.targetCmp.xtype=='tjadmin_pm_box'){
					if(! this.setVerticalDropIndex(e,targetEl,true))// allow insert as well!!!
						return false;
					return true;
				}

				if(this.targetCmp.xtype=='tjadmin_pm_cell') {
					if(! this.setVerticalDropIndex(e,targetEl))
						return false;
					return true;
				}
			}
			return false;
		},
		getSourceCmpFromNode: function(node){
			node.attributes.info.title=node.attributes.text;
			return {	 
				        xtype:TJ.Admin.LM.setXtype(node.attributes.info),// used for drag drop information
						// xtype information is included in node attributes after the Sep 2009 update.
						getServerConfig: function(){
							return node.attributes.info;
						}
				};
			},
        onNodeOver : function(target, dd, e, data){ 
			var targetEl=Ext.fly(target);






			ret=this.checkCanDrop(targetEl,dd,e,data);





			if(ret){		// can drop this, so we are going to paint the styles
				if(this.dropIndex==-1){
					if(this.targetCmp.xtype=='tjadmin_pm_row' && this.targetCmp.items.length) {
						this.targetCmp.body.addClass('panel-insert-right');
					}
					else
					if(this.targetCmp.xtype=='tjadmin_pm_main'){
						if(this.targetCmp.items && this.targetCmp.items.length)
						{
							this.targetCmp.items.last().getEl().addClass('panel-insert-below');

						}
						else{
							this.targetCmp.body.addClass('panel-insert-above');
//							this.targetCmp.addClass('panel-insert-below');

						}
					}
					else{
						this.targetCmp.body.addClass('panel-insert-below');
						targetEl.removeClass('panel-insert-above');
						targetEl.removeClass('panel-insert-below');
					}
				}
				else
				if (this.dropIndex==this.targetIndex) {// dropping above/left
					if(this.targetCmp.xtype=='tjadmin_pm_column') {
						targetEl.removeClass('panel-insert-right');
						targetEl.addClass('panel-insert-left');
					}
					else {
						targetEl.removeClass('panel-insert-below');
						this.targetCmp.body.removeClass('panel-insert-below');
						targetEl.addClass('panel-insert-above');
					}
				} else {
					if(this.targetCmp.xtype=='tjadmin_pm_column') {
						targetEl.removeClass('panel-insert-left');
						targetEl.addClass('panel-insert-right');
					}
					else {
						targetEl.removeClass('panel-insert-above');
						this.targetCmp.body.removeClass('panel-insert-below');
						targetEl.addClass('panel-insert-below');
					}
				}
			} else {

				this.targetCmp.body.removeClass(['panel-insert-above','panel-insert-below']);
	            targetEl.removeClass(['panel-insert-above','panel-insert-below','panel-insert-left','panel-insert-right']);
			}

			if(ret) {
				if (data.copy)
					return 'x-dd-drop-ok-add';
				else {
					if(this.dropIndex==-1)
						return 'x-dd-drop-ok-left';
					else
						return Ext.dd.DropZone.prototype.dropAllowed;

				}

			}
			return Ext.dd.DropZone.prototype.dropNotAllowed;
        },

//      On node drop, we can interrogate the target node to find the underlying
//      application object that is the real target of the dragged data.
//      In this case, it is a Record in the GridPanel's Store.
//      We can use the data set up by the DragZone's getDragData method to read
//      any data we decided to attach.
        onNodeDrop : function(target, dd, e, data){
			var targetEl=Ext.fly(target);


			ret=this.checkCanDrop(targetEl,dd,e,data);
			if(ret){
				config = data.sourceCmp.getServerConfig();
				config.xtype=data.sourceCmp.xtype;

				if(data.copy){		//  reset title for copies{

					config.title='Copy of ' + config.title;


				}
				if(this.dropIndex==-1) {  // append mode
					newCmp=	this.targetCmp.add(config);
					if(newCmp.getEl())
						newCmp.getEl().highlight();

					if(data.sourceCmp.ownerCt && ! data.copy)
						data.sourceCmp.ownerCt.remove(data.sourceCmp);
					this.targetCmp.doLayout();

				} else {
					newCmp = this.targetOwnerCmp.insert(this.dropIndex,config);
					if(newCmp.getEl())
						newCmp.getEl().highlight();
					if(data.sourceCmp.ownerCt  && ! data.copy)
						data.sourceCmp.ownerCt.remove(data.sourceCmp);
					this.targetOwnerCmp.doLayout();
				}
				return true;
			}
			return false;

        }
    });

};



TJ.Admin.LM.Designer = Ext.extend(Ext.Panel,{
//	title: 'Layout Designer',
	mode: 'page',
	layout: 'border',
	frame: false,
	// set and get both support Object only
	getValue: function(){
		return this.pm.getServerConfig();
	},
	setValue: function(value){
//		console.log('Designer Set Value',value, this.pm);
		this.pm.setValue(value);
		this.setActiveItems(this.pm,true);
	},
	initComponent: function (){
		this.tp = new Ext.tree.TreePanel({
			ddGroup:'PMDDGroup',
			title: 'Content Cells',
			region: 'west',
			border: false,
			width:  160,
			split: true,
			autoScroll: true,
			collapsible: true,
			enableDrag: true,
			rootVisible: false,
			root : new Ext.tree.AsyncTreeNode({
					id: 'root',
					text: 'Home'
				}),
			loader: new Ext.tree.TreeLoader({
					dataUrl: '/en/admin/pagemanager:getnodes',
					baseParams: {mode: this.mode}
				}),
			tools: [ { id: 'refresh',
					   handler: function(){ //console.log('hello'); 									
							this.tp.getLoader().load(this.tp.getRootNode());},
						scope: this
				}]
				
		});

		


		this.pm = Ext.ComponentMgr.create( {
				xtype:'tjadmin_pm_main',
				mode: this.mode,
				border: false
				
			});

		this.ts = new Ext.TabPanel({
			region: 'center',
			activeTab: 0,
			border: false,
			items : [ new Ext.Panel( {layout: 'fit',title: 'Designer', items: [this.pm]})]
		
		});

		for (lang in TJ.LANGUAGEDESC) {
			this.ts.add( new TJ.comp.IFramePanel( {
										title:  'Preview ' + TJ.LANGUAGEDESC[lang],
										lang:	lang,
										border: false,
										bodyClasses: ['mceContentBody'],
										stylesheets: [TJ.CLIENTCSS],
										listeners: {activate: {fn: this.preview, scope: this}}
			}));
		}
			
		this.pg = new Ext.grid.PropertyGrid ({
				title: 'Properties',
				propertyNames: {},
				collapsible: true,
				region: 'east',
				border: false,
			split: true,
				width: 200
		});
				
		this.pg.store.sortInfo = null; 
//		this.getColumnModel().config[0].sortable=false;
		this.items = [this.tp,this.ts,this.pg
			];

		this.pg.on('propertychange',this.configChange,this);

 		TJ.Admin.LM.Designer.superclass.initComponent.call(this);
		activeItem=null;
	},
	preview: function(panel){
		panel.setContent('&nbsp');
		panel.body.mask('Loading...','x-mask-loading');
				Ext.Ajax.request({  url: '/'+panel.lang+'/admin/pagemanager:preview',
									params: {info:  Ext.util.JSON.encode(this.pm.getServerConfig())},
									callback: function(options,success,response){
										panel.body.unmask();
										if(success)
											panel.setContent(response.responseText);
										else
											panel.body.mask('Preview Failed');
									},
									scope: this
				});
	},
	configChange: function(source,record, value,old){

		if(this.activeObj)
			this.activeObj.setConfigValue(record,value);
//			console.log(source,record,value,old);

	},
	onDestroy:function() {
		// destroy 
		if(this.pg) {
			this.pg.purgeListeners();
			this.pg.destroy();
			this.pg=null;
		}
		if(this.pm) {
			this.pm.purgeListeners();
			this.pm.destroy();
			this.pm=null;
		}
		if(this.tp) {
			this.tp.purgeListeners();
			this.tp.destroy();
			this.tp=null;
		}

 		TJ.Admin.LM.Designer.superclass.onDestroy.call(this);
	},
	classConfigs:[],
	startPropertyGrid: function(item){
		if(item.serverType=='mainer'){		// no property grid for the main object
			this.loadPropertyGrid(item);
		}
		else
		if(this.classConfigs[item.serverType]){
			this.loadPropertyGrid(item);
		}else{
				if(this.pg.body)
					this.pg.body.mask('Loading...','x-mask-loading');
				Ext.Ajax.request({  url: '/en/admin/pagemanager:getConfigFields',
									item: item,
									params: {serverType: item.serverType},
									callback: function(options,success,response){
										if(this.pg.body)
											this.pg.body.unmask();
										ret = Ext.util.JSON.decode(response.responseText);
										this.classConfigs[item.serverType]=ret;
										this.loadPropertyGrid(item);

	
									},
									scope: this
				});
		}
	},
	loadPropertyGrid: function(item){
	
		
		fields=this.classConfigs[item.serverType].fields;
		
		// clean up old custom editors.
		if(this.pg.customEditors) {
			for (var key in this.pg.customEditors) {this.pg.customEditors[key].destroy();}
		}
		this.pg.customEditors={};
		this.pg.propertyNames={};

		var values=[];

		this.pg.propertyNames['_name']='<b>Name</b>';
		values['_name'] =  item.title;

		// setup new custom editors.
		if(fields) {
			for (key=0;key < fields.length; key++){

				editor=Ext.ComponentMgr.create(fields[key]);
				editor.propertyGrid=this.pg;

				this.pg.customEditors[fields[key].name]	=	new Ext.grid.GridEditor(editor);
				this.pg.propertyNames[fields[key].name] =	fields[key].fieldLabel || fields[key].name;
					if(! item.values)
						item.values={};
					if(item.values[fields[key].name]!==null && typeof(item.values[fields[key].name])!=='undefined'){ // value exists in item
						values[fields[key].name] = item.values[fields[key].name];
					}
					else if(item.values[fields[key].basename]!==null && typeof(item.values[fields[key].basename])!=='undefined'){ // value exists in item
						values[fields[key].name] = item.values[fields[key].name] = item.values[fields[key].basename];
					}
					else{
						values[fields[key].name] = item.values[fields[key].name] = fields[key].value;
					}


			}

		}

		this.pg.setTitle('Properties: ' + this.classConfigs[item.serverType].name);
		this.pg.setSource( values);

	},
    setActiveItems : function(item,force){

        item = this.getComponent(item);

        if(this.activeObj != item || force){

            if(this.activeObj){
				title=this.activeObj.getEl().child('.x-panel-header-text');
				if(title)
					title.setStyle({'font-weight': 'normal'});
               }
			if(this.pg.activeEditor && this.pg.activeEditor)
				this.pg.activeEditor.completeEdit();

			if(item.rendered) {
				this.activeObj=item;

				title=this.activeObj.getEl().child('.x-panel-header-text');
				if(title)
					title.setStyle({'font-weight':'bold'});
//				console.log('startpro', item);
				this.startPropertyGrid(item);
			}


		}

	},
	activeObj: null,
	activateItem: function(item){
	
		this.setActiveItems(item);

	},
	render:function(ct,pos) { 
//		this.deferRender.defer(1000,this,[ct,pos]); return
		TJ.Admin.LM.Designer.superclass.render.call(this, ct,pos); 
		TJ.Admin.LM.initDragZone(this);
//		console.log('designer render');
//		this.setActiveItems.defer(10,this,[this.pm]);


	}, // eo function onRender 
	deferRender: function(ct,pos){
		console.log('asdf');
		TJ.Admin.LM.Designer.superclass.render.call(this, ct,pos); 
		TJ.Admin.LM.initDragZone(this);


	}

});
