var CourTreePanel = function(config) {
	var th = this;
	
	this.CourId = config['idToLoad'];
	this.indexToLoad = config['idToLoad'];
	
	this.selected_type = null;
	this.selected_int_id = null;
	this.selected_link_id = null;
	this.selected_line_id = null;
	
	this.passcode = '';
	
	this.setCubeTextById = function(id, text){
		var t = th.getRootNode();
		t.eachChild(function(node){
			if(typeof node != "function"){
				node.eachChild(function(ch){
					if(typeof ch != "function"){
						if(ch.attributes.main_id == id){
							ch.setText(text);
						}
					}
				})
			}
		});
	}
	
	this.setLineTextById = function(id, text){
		var t = th.getRootNode();
		t.eachChild(function(node){
			if(typeof node != "function"){
				if(node.attributes.int_id == id){
					node.setText(text);
				}
			}
		});
	}
	
	/* НАЧАЛО УПРАВЛЕНИЯ КУБАМИ И ЛИНИЯМИ */
	/* Сейчас не используется, только как задумка */
	
	this.getCubePosById = function(id){
		var x = -1;
		var y = -1;
		
		var t = th.getRootNode();
		for(var i = 0; i < t.childNodes.length; i++){
			x++; y = -1;
			var r = t.childNodes[i];
			for(var j = 0; j < r.childNodes.length; j++){
				y++;
				if(r.childNodes[j].attributes.main_id == id){
					return [x,y];
				}
			}
		}		
		return [x,y];
	}
	
	this.getLinePosById = function(id){
		var t = th.getRootNode();
		for(var i = 0; i < t.childNodes.length; i++){
			if(t.childNodes[i].attributes.int_id == id){
				return i;
			}
		}		
		return i;
	}
	
	this.moveCube = function(from, to){
		var c = th.getCube(from);
		var c_bef = th.getCube(to);
		
		th.getLineByPos(to[0]).insertBefore(c, c_bef);
	}
	
	this.copyCube = function(from, to, new_id){
		var c = th.getCopyOfCube(from, new_id);
		var c_bef = th.getCube(to);
		
		th.getLineByPos(to[0]).insertBefore(c, c_bef);
	}
	
	this.deleteCube = function(from){
		var c = th.getCube(from);
		c.remove();
	}
	
	this.insertCube = function(cube, to){
		var c_bef = th.getCube(to);
		
		th.getLineByPos(to[0]).insertBefore(cube, c_bef);
	}
	
	this.changeCubeId = function(c, new_id){
		c.attributes.link_id = new_id;
		c.attributes.id = 'cube_link_' + new_id;
		
		return c;
	}
	
	this.getCube = function(from){
		var tr = th.getNodeById('cube_link_' + from);
		if(tr != null){
			return tr;
		}else{
			var t = th.getRootNode();
			var r = t.item(from[0])
			r.expand(false, false);
			return r.item(from[1]);
		}
	}
	
	this.getLineByPos = function(from_line){
		var t = th.getRootNode();
		return t.item(from_line);
	}
	
	this.getLineById = function(from_line){
		var t = th.getRootNode();
		for(var i = 0; i < t.childNodes.length; i++){
			if(t.childNodes[i].attributes.int_id == from_line){
				return t.childNodes[i];
			}
		}
		return null;
	}

	this.getCopyOfCube = function(from, new_id){
		var c = th.getCube(from);
		c = th.changeCubeId(c, new_id);
		
		return c;
		
	}
	
	/*this.getLinePosById = function(id){
		var t = th.getRootNode();
		var x = -1;
		for(var i = 0; i < t.childNodes.length; i++){
			if(t.childNodes[i].attributes.int_id == from[0]){
				x = i; break;
			}
		}
		return x;
	}
	
	this.smartMoveCube = function(from, to){
		var lfrom = from;
		if(th.getLinePosById(from[0]) != -1){
			lfrom[0] = th.getLinePosById(from[0]);
		}
		
		var lto = to;
		if(th.getLinePosById(from[0]) != -1){
			lfrom[0] = th.getLinePosById(from[0]);
		}
		
		
		
	}*/
	
	/* КОНЕЦ УПРАВЛЕНИЯ КУБАМИ И ЛИНИЯМИ */

	this.tb_button_add_line = new Ext.Button({
		text: '<img src="img/plus_small_bbg.gif" alt="New" /><img src="img/folder.gif" alt="line" />&nbsp;',
		tooltip: 'Добавляет новую линию (набор кубиков)',
		handler: function() {
			app.edit_line.add_line(th);
		},
		scope: this
	});

	this.tb_button_add_cube = new Ext.Button({
		text: '<img src="img/plus_small_bbg.gif" alt="New" /><img src="img/leaf.gif" alt="cube" />&nbsp;',
		tooltip: 'Добавляет новый кубик в линию',
		handler: function() {
			app.edit_form.show(th, 0, this.selected_line_id);
		},
		scope: this
	});

	this.tb_button_edit = new Ext.Button({
		disabled: true,
		text: '<img src="img/edit_bbg.gif" alt="Edit" />',
		tooltip: 'Редактирует линию или кубик (выберите что-нибудь ниже в дереве)',
		handler: function() {
			if (this.selected_type == 'line') {
				app.edit_line.edit_line(th, this.selected_int_id);
			} else if (this.selected_type == 'cube') {
				app.edit_form.show(th, this.selected_int_id);
			}
		},
		scope: this
	});
	
	/*this.tb_button_save = new Ext.Button({
		text: 'Save',
		handler: function() {
			app.tree_panel.savetree();
		},
		scope: this
	});*/

	this.tb_button_delete = new Ext.Button({
		disabled: true,
		text: '<img src="img/del_bbg.gif" alt="Delete" />',
		tooltip: 'Удаляет линию или кубик (выберите что-нибудь ниже в дереве)',
		handler: function() {
			if (this.selected_type == 'line') {
				app.delete_line.delete_line(th,this.selected_int_id);
			} else if (this.selected_type == 'cube') {
				app.delete_cube_link.delete_cube_link(th,this.selected_link_id);
			}
			th.cacheUnselect();
		},
		scope: this
	});

	this.tb = new Ext.Toolbar({
		items: [this.tb_button_add_line, this.tb_button_add_cube, this.tb_button_edit, this.tb_button_delete/*, this.tb_button_save*/]
	});
	
	this.tb.disable();

	this.config = new Array();
	for(t in config){
		this.config[t] = config[t];
	}
	
	this.combo = new ComboTree({targetEx: th});
	
	this.reloadEx = function(index){
		this.indexToLoad = index;
		if(this.getRootNode().isExpanded()){
			var lo = this.getLoader();
			lo.load(this.getRootNode());
		}
		this.setCourId(index);
		this.getRootNode().expand();
//		th.passcode = "";
		return this;
	}
	
	this.reloadLine = function(index){
		this.lineToLoad = index;
		var r = th.getLineById(index);
		if(r != null){
			try{
				r.reload();
			}
			catch(e)
			{
				dd([index, r]);
			}
		}
	}
	
	this.askForPass = function(txt){
		Ext.Msg.prompt('Auth', txt, function(btn, text) {
			if (btn == 'ok' && text.trim()) {
				th.passcode = text;
				th.nodeToLoad.reload();
				//th.reloadEx(th.indexToLoad);
			};
			if (btn == 'cancel') {
				
			};
		}, this, false, "");
	}
	
	this.config = {
		id: 'tree',
		region: 'west',

		useArrows: true,
		animate: true,
		enableDD: true,
		ddGroup: 'treeDD',
		rootVisible: true,
		title: 'Содержание курса',

		width: 250,
		minSize: 175,
		maxSize: 450,
		split: true,
		collapsible: true,
		margins: '32 0 4 4',
		cmargins: '32 4 4 4',
		autoScroll: true,
		containerScroll: true,
		tbar: this.tb,
		bbar: this.combo,

		//dataUrl: 'actions/tree.get.json.php',
		loader: new Ext.tree.TreeLoader({
			dataUrl:'actions/line.get.json.php',
			clearOnLoad: true,
			baseParams : {
			    id: th.config['idToLoad'],
			    tree_id: th.config['id']
			},
			listeners: {
				beforeload: function(ob, node, cb){
					if(th.passcode){
						ob.baseParams['pass'] = th.passcode;
						th.passcode = "";
					}
					if(th.indexToLoad != ''){
						ob.baseParams['id'] = th.indexToLoad;
						
						if(th.lineToLoad){
							ob.dataUrl = 'actions/line.get.json.php';
						}
					}
				},
				load: function(ob, node, resp){
					ob.baseParams['pass'] = "";
					// если нет доступа..
					var r = Ext.util.JSON.decode(resp.responseText); 
					if(r.lock == 1){
						th.nodeToLoad = node;
						//th.nodeToLoadType = node.getDepth() == 0 ? "source"
					
						th.askForPass(r.warning);return;
					};
					
					th.nodeToLoad = null;
					ob.baseParams['node'] = "source";
					th.getRootNode().attributes.cour_id = th.CourId;
					th.rebuildNodeInPanel(th.toSaveNode);
					// перезапрашиваем уровень доступа только если грузим root
					if(th.indexToLoad != ''){
						conn = new Ext.data.Connection();
						conn.request({
							url: 'actions/is.owner.php',
							method: 'GET',
							success: function(data){
								if(data.responseText == 1){
									th.setOwner(1);
									th.tb.enable();
								}else{
									th.setOwner(0);
									th.tb.disable();
								}
								th.indexToLoad = '';
							},
							failure: function(){
								//TODO: Сабж
								
							},
							params: {id: th.CourId}
						});
					}
					
				}
			}
		}),

		root: {
			id: 'source',
			nodeType: 'async',
			draggable: false,
			//allowDrop: false,
			text: th.config['rootTitle'],
			isOwner: function(){
				return th.isOwner();
			}
		},
		listeners: {
			nodedragover: {
				fn: this.notallowed,
				scope: this
			},
			nodedrop: {
				fn: this.savetree,
				scope: this
			},
			beforenodedrop: {
				fn: this.trytocopy,
				scope: this
			},
			startdrag: {
				fn: this.startD,
				scope: this
			}
		}
	};
	
	for(t in config){
		this.config[t] = config[t];
	}
	
	this.setOwner = function(ow){
		th.getRootNode().attributes.owner = ow;
	}
	
	this.isOwner = function(){
		return th.getRootNode().attributes.owner;
	}
	
	this.getCourId = function(){
		return this.CourId;
		//return this.config['idToLoad'];
	}
	
	this.setCourId = function(id){
		this.CourId = id;
	}
	
	CourTreePanel.superclass.constructor.call(this, this.config);

	this.getRootNode().on('load', function(root_node) {
		//dd(this.getRootNode().getPath());
		//this.expandAll();
		this.collapseAll();
	}, this);
	
	this.toSaveNode = null;

	this.rebuildNodeInPanel = function(node){
		if(node == null)return;
		if(node.getDepth() == 0){
			node.expand();
			return;
		}
		//dd(node.attributes);
		var req_line_id = node.attributes.type == 'line' ? node.attributes.id : node.attributes.line_id;
		if (!req_line_id) {
			msg_error('No line is specified');
		}
		var req_line_node = node.attributes.type == 'line' ? node : node.parentNode;
		var req_line_cubes = new Array();
		if (!req_line_node.childNodes.length && req_line_node.hasChildNodes()) {
			// TreePanel doesn't render collapsed child nodes after loading
			req_line_node.expand(false, false);
			req_line_node.collapse(false, false);
		}
		
		for (var i = 0; i < req_line_node.childNodes.length; i++) {
			req_line_cubes[i] = req_line_node.childNodes[i].attributes.int_id;
		}
		//dd(req_line_cubes);
		//cubes_store.baseParams['c[]'] = req_line_cubes;
		var new_cubes = new Array();
		for (var i = 0; i < req_line_cubes.length; i++) {
			if (!app.panel.cubes_cache[req_line_cubes[i]]) {
				new_cubes[new_cubes.length] = req_line_cubes[i];
			}
		}
		/*if(node.attributes.type == 'line')
			dd(['click', req_line_cubes]);
		else dd(['click', node.attributes]);*/
		var scroll_to_cube_id = node.attributes.type == 'cube' ? node.attributes.int_id : 0;
		
		if (new_cubes.length) {
			Templates.loading_tpl.overwrite(app.panel.body);
			app.panel.cubes_store.load({
				add: true,
				params: {'c[]': new_cubes},
				req_line_cubes: req_line_cubes,
				scroll_to_cube_id: scroll_to_cube_id
			});
		} else {
			app.panel.resort_panel(req_line_cubes, scroll_to_cube_id);
		}
		//dd('asd');
		// Toolbar
		if(th.isOwner()){
			this.tb_button_edit.setDisabled(false);
			this.tb_button_delete.setDisabled(false);
		}
		/*// Cache
		this.selected_type = node.attributes.type;
		this.selected_int_id = node.attributes.int_id;
		//this.selected_int_id = node.attributes.main_id;
		this.selected_link_id = node.attributes.type == 'line' ? null : node.attributes.link_id;
		this.selected_line_id = node.attributes.type == 'line' ? node.attributes.int_id : node.attributes.line_id;*/
		th.cacheSelected(node);
		//
		return true;
	}
	
	this.cacheUnselect = function(){
		this.cacheSelected(null);
	}
	
	this.cacheSelected = function(node){
		if(node == null){
			this.selected_type = this.selected_int_id = this.selected_link_id = this.selected_line_id = null;
		}
		// Cache
		this.selected_type = node.attributes.type;
		this.selected_int_id = node.attributes.int_id;
		//this.selected_int_id = node.attributes.main_id;
		this.selected_link_id = node.attributes.type == 'line' ? null : node.attributes.link_id;
		this.selected_line_id = node.attributes.type == 'line' ? node.attributes.int_id : node.attributes.line_id;
	}
	
	this.on('click', function(node, e) {
		if(node.attributes.type == 'cube' || (node.attributes.type == 'line' && node.isExpanded())){
			th.rebuildNodeInPanel(node);
		}else{
			th.toSaveNode = node;
			node.expand(false, false);
		}
		th.cacheSelected(node);
		//dd(node);
		//dd([this.selected_line_id, node.attributes]);
		/*if(node == null)return;
		if(node.getDepth() == 0){
			node.expand();
			return;
		}
		
		var req_line_id = node.attributes.type == 'line' ? node.attributes.id : node.attributes.line_id;
		if (!req_line_id) {
			msg_error('No line is specified');
		}
		var req_line_node = node.attributes.type == 'line' ? node : node.parentNode;
		var req_line_cubes = new Array();
		if (!req_line_node.childNodes.length && req_line_node.hasChildNodes()) {
			// TreePanel doesn't render collapsed child nodes after loading
			req_line_node.expand(false, false);
			req_line_node.collapse(false, false);
		}
		
		for (var i = 0; i < req_line_node.childNodes.length; i++) {
			req_line_cubes[i] = req_line_node.childNodes[i].attributes.int_id;
		}
		//dd(req_line_cubes);
		//cubes_store.baseParams['c[]'] = req_line_cubes;
		var new_cubes = new Array();
		for (var i = 0; i < req_line_cubes.length; i++) {
			if (!app.panel.cubes_cache[req_line_cubes[i]]) {
				new_cubes[new_cubes.length] = req_line_cubes[i];
			}
		}
		if(node.attributes.type == 'line')
			dd(['click', req_line_cubes]);
		else dd(['click', node.attributes]);
		var scroll_to_cube_id = node.attributes.type == 'cube' ? node.attributes.int_id : 0;
		if (new_cubes.length) {
			Templates.loading_tpl.overwrite(app.panel.body);
			app.panel.cubes_store.load({
				add: true,
				params: {'c[]': new_cubes},
				req_line_cubes: req_line_cubes,
				scroll_to_cube_id: scroll_to_cube_id
			});
		} else {
			app.panel.resort_panel(req_line_cubes, scroll_to_cube_id);
		}
		//dd('asd');
		// Toolbar
		if(th.isOwner()){
			this.tb_button_edit.setDisabled(false);
			this.tb_button_delete.setDisabled(false);
		}
		// Cache
		this.selected_type = node.attributes.type;
		this.selected_int_id = node.attributes.int_id;
		//this.selected_int_id = node.attributes.main_id;
		this.selected_link_id = node.attributes.type == 'line' ? null : node.attributes.link_id;
		this.selected_line_id = node.attributes.type == 'line' ? node.attributes.int_id : node.attributes.line_id;;
		//
		return true;*/
	});
}

Ext.extend(CourTreePanel, Ext.tree.TreePanel, {
	notallowed: function (evt) {	
	//TODO: исправить не точное позиционирование курсора над папками
		typeTarget = evt.target.attributes.type;
		typeSource = evt.dropNode.attributes.type;	
		var sourceA = evt.dropNode.attributes;
		var targetA = evt.target.attributes;
		
		if(!evt.target.getOwnerTree().isOwner() || !evt.dropNode.getOwnerTree().isOwner()){
			evt.cancel = true; return;
		}
		
		if(evt.target.attributes.cour_id == undefined){
			evt.cancel = true;
			return;
		}
		if(typeSource == 'line'){
			if((typeTarget == 'line' && evt.point == 'append') || typeTarget == 'cube'){  
				evt.cancel = true; return;
			}
			//в то же дерево копировать линию нельзя
			if(sourceA.tree_id == targetA.tree_id){
				if (evt.rawEvent.ctrlKey) {
					evt.cancel = true; return;
				}
			}else{
				// если в другом дереве тот же курс, то тоже нельзя
				if(sourceA.cour_id == targetA.cour_id){
					evt.cancel = true; return;
				}else{
					// на root дропать можно без ограничений, а вот есть не root
					if(evt.target.parentNode != null){
						//если в этом дереве уже есть такой курс, то низзя
						evt.target.parentNode.eachChild(function(node){
							if(typeof node != "function"){
								if(node.attributes.int_id == sourceA.int_id){
									evt.cancel = true;
									return;
								}
							}
						});
					}
				}
			}
		}
		if(typeSource == 'cube'){
			if(evt.target.parentNode == null){
				evt.cancel = true;
			}
			/*// пока копирование кубиков отключено
			if (evt.rawEvent.ctrlKey) {
				evt.cancel = true; return;
			}*/
			// --
			if((typeTarget == 'line' && evt.point != 'append')){
				evt.cancel = true;
			}
            if((typeTarget == 'cube' && evt.point == 'append')){
				evt.cancel = true;
			}
		}
		if(!evt.cancel){
			evt.dropNode.attributes.line_id = (typeof(evt.target.attributes.line_id) != "undefined") ? evt.target.attributes.line_id : evt.target.attributes.int_id;
		}		
		
	},
	
	savetree: function(evt){
		//dd('dropped');
		//return false;
		var temp = new Array();
		temp['wtd']	= evt.rawEvent.ctrlKey ? "copy" : "move";
		//dd(['save',evt.dropNode]);
        typeSource = evt.dropNode.attributes.type;
        if(typeSource == "cube"){
            var i = 1;
            temp['type']    = 'cube';
            temp['id']      = evt.dropNode.attributes.int_id;
            temp['link']    = evt.dropNode.attributes.link_id;
            temp['line']    = evt.dropNode.parentNode.attributes.int_id;
            temp['line_old']    = evt.dropNode.attributes.old_line_num;
            temp['position_old']    = evt.dropNode.attributes.old_line_pos;
            temp['cour']	= this.getCourId();
            evt.dropNode.parentNode.eachChild( function(node){
               if(typeof(node) != "function"){
                   if(node.attributes.link_id == temp['link']){
                       temp['new_position']   = i;
                   }else{
                       i++;
                   }
               }
            });
        }else{
            var i = 1;
            temp['type']    	= 'line';
            temp['id']  		= evt.dropNode.attributes.int_id;
            temp['cour_to']		= this.getCourId();
            temp['position_old']    = evt.dropNode.attributes.old_line_pos;
            evt.dropNode.parentNode.eachChild( function(node){
               if(typeof(node) != "function"){
                   if(node.attributes.int_id == temp['id']){
                       temp['new_position']   = i;
                   }else{
                       i++;
                   }
               }
            });
        }

        /*var place_now = this.getCubePosById(temp['id']);
		var place_old = [this.getLinePosById(temp['line_old']), temp['position_old']]; 
		this.copyCube(place_now, place_old, 'xxx');*/
		var myMask = new Ext.LoadMask('tree', {msg:"Сохраняем..."});
		myMask.show();

		var conn = new Ext.data.Connection();
		conn.request({
			url: 'actions/tree.save.xml.php',
			method: 'GET',
			success: function(data){
				if(temp['type'] == 'cube'){
					app.tree_panel.reloadLine(temp['line']);
					app.tree_panel_out.reloadLine(temp['line']);
					
					app.tree_panel.reloadLine(temp['line_old']);
					app.tree_panel_out.reloadLine(temp['line_old']);
				}
			//TODO: Сабж
			},
			failure: function(){
			//TODO: Сабж
				
			},
			params: temp
		});
		myMask.hide();
		//app.panel.resort_panel();
		this.fireEvent('click', evt.target.parentNode);
		//dd(temp);
	},
	
	trytocopy: function(evt){
		//dd(['before',evt.dropNode]);
		
		//evt.dropNode.attributes.old_line_num = 'oldxx-' + evt.dropNode.attributes.line_id;
		//dd(['before',evt.dropNode]);
		/*if(evt.rawEvent.ctrlKey){
			var n = evt.dropNode; 
			var tmp = n.attributes;
			tmp.id = "xxx";
			tmp.link_id = "xxx";
			var copy = new Ext.tree.TreeNode( 
					Ext.apply({}, tmp) 
			);
			evt.dropNode = copy; 
		}*/
		
		return true;
	},
	
	startD: function(panel, node, evt){
		if(node.attributes.type == 'cube'){
			node.attributes.old_line_num = node.attributes.line_id;
			var t = node.parentNode.childNodes.length;
			for(var i = 0; i < t; i++){
				if(node.parentNode.childNodes[i] == node){
					node.attributes.old_line_pos = i;
					break;
				}
			}
		}
		if(node.attributes.type == 'line'){
			var t = node.parentNode.childNodes.length;
			for(var i = 0; i < t; i++){
				if(node.parentNode.childNodes[i] == node){
					node.attributes.old_line_pos = i;
					break;
				}
			}
		}
		
	}
});





