window.loading = {};

var viewDefaults = {
	bufferedView: {
		nearLimit: 250,
		loadMask: {
			msg: 'Ждите ответа… Ждите ответа… Не ждите ответа…'
		}
	},
	bufferedReader: {
		root:            'list.items',
		versionProperty: 'list.version',
		totalProperty:   'list.total_count',
		id: 'id'
	},
	bufferedStore: {
		//autoLoad: true,
		listeners : {
			load: function (s) {
				window.grid_request_date = DateCache ();
				
				//console.log ('store base params' + DumpFields (s.baseParams));
				//console.log ('store last opts' + DumpFields (s.lastOptions.params));
			}
		},
		bufferSize: 250
		//sortInfo: {field: 'id', direction: 'ASC'},
		//url: web_app_request.base_uri+'/auctions/list.json/all',
	},
	panelConf: {
		region: 'center',
		autoScroll: true,
		collapsible: false,
		collapsed: false
	},
	defaultView: 'grid',
	sidebar: {
		cls: 'mainpage-sidebar',
		columnWidth: .3,
		width: 300,
		region: 'east',
		autoScroll: true,
		collapsible: false,
		collapsed: false
	},
	tabbar: {
		//split:true,
		//height: 30,
		//margins:'35 0 5 5',
		//cmargins:'35 5 5 5',
		//layout: 'accordion',
		
		//title: '12345',
		
		//autoHeight: true,
		collapsible: false,
		activeTab: 0,
		id: 'view-switcher',
		
		xtype: 'tabpanel'
	},
	columnTree: {
		region: 'center',
		frame: false,
		rootVisible: true,
		animate: true, 
		autoScroll: true,
		layout: 'fit',
		enableDD:true,
		containerScroll: true,
		dropConfig: {appendOnly:true}
	},
	grid: {
		collapsible: false,
		collapsed: false,
		enableDragDrop: false,
		columnWidth	: .7,
		autoHeight: false,
		region: 'center',
		layout:'fit',
		xtype: 'gridpanel',
		listeners: {
			/*activate: function (p) {
				//p.syncSize();
				if (p.getStore())
					p.view.updateLiveRows (p.view.lastIndex, true, true);
			},*/
			activate: function (p) {
				var s = p.getStore();
				console.log (p.id + ' activated');
				if (p.rendered)
					s.reload();
			},
			render: function (p) {
				var s = p.getStore();
				console.log (p.id + ' rendered');
				s.load();
			}
		},
		loadMask: {
			msg: 'Матрица: перезагрузка...'
		}
	},
	portal: {
		//region:'south',
		collapsible: false,
		//minSize: '90%',
		title: 'Widgets',
		//autoHeight: true,
		xtype:'portal'	
	}
};

var layoutDefaults = {
	title: 'FIXME FIXME FIXME'
};

function CreateLayout (config, layoutConfig, views) {
	
	/*Ext.ux.grid.livegrid.Store.prototype.sortData = function (f, direction) {
		console.log ('dir: '+direction);
		direction = direction || 'DESC';
		var st = this.fields.get(f).sortType;
		var fn = function(r1, r2){
			var v1 = st(r1.data[f]), v2 = st(r2.data[f]);
			return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
		};
		this.data.sort(direction, fn);
	};*/
	
	Ext.layout.Accordion.prototype.beforeExpand = function(p, anim){
		p.wanting=true;
        var ai = this.activeItem;
        if(ai){
            if(this.sequence){
                delete this.activeItem;
                if (!ai.collapsed){
                    ai.collapse({callback:function(){
                        p.expand(anim || true);
                    }, scope: this});
					p.wanting=false;
                    return false;
                }
            }else{
                ai.collapse(this.animate);
            }
        }
        this.activeItem = p;
        if(this.activeOnTop){
            p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild);
        }
        this.layout();
		p.wanting=false;
    };
	
	Ext.layout.Accordion.prototype.onLayout = function (ct, target) {
		
		Ext.layout.Accordion.superclass.onLayout.call(this, ct, target);
		
		var tabAccItems = ct.items.items;
		var l = tabAccItems.length;

		for (var t = 0; t < l; t++) {
			tabAccItems[t].on('beforecollapse', function(p){
				for (var i = 0; i < l; i++) {
					if (tabAccItems[i].wanting) 
						return true;
				}
				return false;
			})
		}
	};
	
	var tabs = [];
	
	console.log ('start');
	
	for (var view_counter in views) {
		
		var current_view = views[view_counter];
		
		if (!config[current_view]) {
			continue;
		}
		
		console.log ('before store init '+ current_view);
		
		receivedConf = config[current_view];
		
		// make config copy
		var conf = Clone (viewDefaults);
		
		// recursive (level == 1) version of Ext.apply
		Merge (conf, receivedConf);
		
		var viewItems = [];
		
		var tid;
		
		if (conf.defaultView == 'grid') {
		
			var grid = new LiveGrid (conf, current_view);
			
			viewItems.push (grid);
			
			tid = 'tab-' + grid.id;
			
			if (!window.gridList)
				window.gridList = {};
			
			window.gridList[grid.id] = grid;
			
		} else if (conf.defaultView == 'columnTree') {
			var root = new Ext.tree.AsyncTreeNode (conf.columnTreeRoot);
			
			conf.columnTree.root = root;
			
			var ct = new Ext.tree.ColumnTreePanel (conf.columnTree);
			
			viewItems.push (ct);
			
			tid = 'tab-' + conf.columnTree.id;
			
		} else if (conf.defaultView == 'panel') {
		
			viewItems.push (conf.panelConf);
			
			tid = 'tab-' + conf.panelConf.id;
		}
		
		
		if (conf.containsSidebar) {
		
			if (conf.sidebar.grid) {
				
				viewItems.push (new LiveGrid (conf.sidebar.grid, current_view+'_s', 1));
				
			} else {
				viewItems.push (conf.sidebar);
			
			}
			
			console.log ('with sidebar '+ current_view);
			
			//console.log (DumpFields (conf.sidebar));
		}
		
		tabConf = {
			title: conf.title,
			layout: 'border',
			defaults: {
				collapsible: true,
				split: true
			},
			listeners: {
				activate: function (p) {
					var centralItem = p.items.items[0];
					centralItem.fireEvent ('activate', centralItem);
				} 
			},
			items: viewItems
		};
		
		if (tid && tid != 'tab-') {
			tabConf.id = tid;
		}
		
		tabs.push (tabConf);
		
		console.log ('view initialized');
		
	}

	var accordion = [];
	
	if (tabs.length == 1) {
		accordion.push (tabs[0]);
		
		if (tabs[0].items[0] instanceof Ext.grid.GridPanel) {
			window.activeGridId = tabs[0].items[0].id;
		}

	} else {
		var layoutConf = Clone (layoutDefaults);
		Merge (layoutConf, layoutConfig);
		
		var tabBar = Ext.apply (conf.tabbar, {items: tabs});
		
		if (!conf.containsPortal) {
			accordion.push (tabBar);
		} else {
			accordion.push(new Ext.Panel ({
				layout: 'fit',
				title: layoutConf.title,
				items: [tabBar]
			}));
		}
	}

	console.log ('accordion');
	
	// create some portlet tools using built in Ext tool ids
	var tools = [{
		id:'gear',
		handler: function(){
			Ext.Msg.alert('Message', 'The Settings tool was clicked.');
		}
	},{
		id:'close',
		handler: function(e, target, panel){
			panel.ownerCt.remove(panel, true);
		}
	}];
	
	if (conf.containsPortal) {
		var portal = new Ext.ux.Portal (conf.portal, {
			items:[{
				columnWidth:.33,
				style:'padding:10px 0 10px 10px',
				items:[{
					layout:'fit',
					tools: tools,
					title: 'привет',
					contentEl: 'About'
					//html: '2	'
					//items: new SampleGrid([0, 2, 3])
				},{
					title: 'Another Panel 1',
					tools: tools,
					contentEl: 'Rec1'
					//html: '1a'
				}]
			},{
				columnWidth:.33,
				style:'padding:10px 0 10px 10px',
				items:[{
					title: 'Panel 2',
					tools: tools,
					html: '2'
				},{
					title: 'Another Panel 2',
					tools: tools,
					html: '2a'
				}]
			},{
				columnWidth:.33,
				style:'padding:10px',
				items:[{
					title: 'Panel 3',
					tools: tools,
					html: '3'
				},{
					title: 'Another Panel 3',
					tools: tools,
					html: '3a'
				}]
			}]
		});
		
		accordion.push (portal);
		
		console.log ('portal ok');
	}
	// console.log (DumpFields(accordion[0]) + DumpFields(accordion[1]));
	
	var layout = 'accordion';
	if (!conf.containsPortal) {
		layout = 'fit';
	}
	
	var viewport = new Ext.Viewport({
		layout:'border',
		x: 0,
		y: 0,
		listeners: {
			beforestatesave: function () {return false},
			beforestaterestore: function () {return false},
			beforerender: function () {
				var tp = Ext.getCmp ('top-panel');
				tp.setHeight(Ext.getDom ('top').clientHeight);
				//tp.ownerCt.doLayout();
			},
			resize: function () {
				var tp = Ext.getCmp ('top-panel');
				tp.setHeight(Ext.getDom ('top').clientHeight);
				//tp.ownerCt.doLayout();
			}
		},
		items:[{
			region: 'north',
			xtype: 'panel',
			id: 'top-panel',
			contentEl: 'top'
		}, {
			region:'center',
			id:'center-panel',
			split:true,
			//height: 30,
			//layout: 'accordion',
			layout: layout,
			collapsible: false,
			items: accordion
		}]
	});
	
	console.log ('view port ok');
	
	var tabbar = Ext.getCmp ('view-switcher');
	
	if (tabbar) {
		
		tabbar.activate (0);
		
		var token = location.hash.replace(/#/g,'');
		if (token){
			var x = token.split(':');
			console.log ('autoactivate: tab-' + x[1]);
			tabbar.activate ( 'tab-' + x[1] );
		}
		
		
		if (window.gridList && window.gridList[tabbar.getActiveTab ().id.replace (/tab-/, '')]) {
			window.activeGridId = tabbar.getActiveTab ().items.items[0].id;
		} else {
			window.activeGridId = null;
		}
		
		Ext.History.init();
		
		tabbar.on('tabchange', function(tabPanel, tab){
	    	Ext.History.add(':' + tab.id.replace (/tab-/, ''));
			
			if (window.gridList && window.gridList[tabbar.getActiveTab ().id.replace (/tab-/, '')]) {
				window.activeGridId = tabbar.getActiveTab ().items.items[0].id;
			} else {
				window.activeGridId = null;
			}
	    });
		
		Ext.History.on('change', function(token){
			
	        if (token) {
				var x = token.split(':');
				console.log ('autoactivate: tab-' + x[1]);
				tabbar.activate ( 'tab-' + x[1] );
	        }
			
	    });	
			
	}
	
}

function LiveGrid (receivedConf, currentView, mergeConf) {
	
	var conf = receivedConf;
	
	if (mergeConf) {
		conf = Clone (viewDefaults);
		Merge (conf, receivedConf);
	}
	
	var bufferedSelectionModel = new Ext.ux.grid.livegrid.RowSelectionModel ();
	
	var bufferedView = new Ext.ux.grid.livegrid.GridView (conf.bufferedView); 

	var colModel = new Ext.grid.ColumnModel (conf.model);
	
	var recordDef = new Ext.data.Record.create (conf.record);
	
	console.log ('before reader '+ currentView);
	
	var bufferedReader = new Ext.ux.grid.livegrid.JsonReader (
		conf.bufferedReader, recordDef
	);
	
	var bufferedDataStore = new Ext.ux.grid.livegrid.Store (
		Ext.apply (conf.bufferedStore, {
			reader: bufferedReader,
			storeId: currentView + '_store'
		})
	);
	
	console.log ('before grid '+ currentView);
	
	// we need to reapply config here because we create new objects
	// and we must transfer it to grid
	var gridProps = Ext.apply (conf.grid, {

		ds: bufferedDataStore,
		cm: colModel,
		sm: bufferedSelectionModel,
		
		view: bufferedView

	});
	
	if (!conf.grid.bbar) {
		conf.grid.bbar = [
			'<input type="button" value="Обновить" onclick="Ext.getCmp(\''+conf.grid.id+'\').getStore().reload()"/>'
		];
	}
	
	// HACK
	if (!conf.grid.title) {
		conf.grid.header = false;
	}
	
	console.log ('after grid '+ currentView);
	
	return new Ext.grid.GridPanel (gridProps);

}

function ApplyFilters () {
	
	if (! window.activeGridId)
		return;
	
	var formData = FormValuesHash (GetDom ('filters'));
	
	console.log (DumpFields (formData));
	
	var store = window.gridList[window.activeGridId].getStore ();
	
	store.baseParams = formData;
	
	store.reload ();
	
	return;
	
	var gridListCount = window.gridList.length;
	for (var i = 0; i < gridListCount; i++) {
		var currGrid = gridList[i];
		if (!currGrid.rendered)
			continue;
		
		var store = currGrid.getStore ();
		
		store.baseParams = {hello: 'everyone!'};
	}
}

function ReloadTree (treeId, button) {
	if (button) {
		button.disabled = true;
	}
	
	Ext.getCmp (treeId).getRootNode().reload(function (){
		if (button) {
			button.disabled = false;
		}
	});
}
