"use strict";

var _ = require("lodash"),
	Condicio = require("condicio"),
	Node = require("./Node.js"),
	Utility = require("../Utility.js"),
	CvtForJson = require("../CvtForJson.js"),
	ParamValidation = require("../ParamValidation.js"),
	Command = require("./Command.js");

/**
 * @class View3D.DrawingRootNode
 * Drawing文件对应模型根节点
 *
 * 不应该直接创建,应该由{@link NodeFactory}创建出来
 */
function DrawingRootNode(session, objectID, name) {
	this.objectID = objectID;
    this.session = session;
    this.name = name;
};

DrawingRootNode.prototype = _.create(Node.prototype, {
    constructor: DrawingRootNode
});

/**
 * 创建分离Command
 * 将子节点从父节点上分离,分离后会重新创建一个新的节点代表分离的节点回送给用户
 * 原因是通过findDescendNodes或者点选获取的Drawing下的节点仅限于放在Drawing之下使用
 * 而返回的节点可以支持放置在Drawing之外使用
 * 
 * @param {Node[]}     	nodes 			需要分离的节点
 * @param {Function} 	callback		返回分离结果
 * @param {Error}       callback.error 	返回错误
 * @param {Node[]}		callback.nodes  返回分离后的节点
 *
 * @return {View3D.Command}
 */
DrawingRootNode.prototype.createDetachCommand = function (nodes, callback) {
	ParamValidation.checkIsTypeArray(nodes, Node, "The  type of nodes must be 'Node Array' and valid!");
	Condicio.checkIsFunction(callback, "The type of callback must be 'Function'!");
	
	var callbackWrapper = function (error, result) {
		if (!error) {
			var nodes = result.nodes;

			var tempNodes = [];
			for (var i = 0; i < nodes.length ; ++i) {
				if (nodes[i].nodeID !== "")
					tempNodes.push(new Node(this.session, nodes[i].nodeID, nodes[i].name));
				else
					tempNodes.push(null); // 没找到给一个空
			}

			callback(error, tempNodes);
		}
		else {
			callback(error, null);
		}
	};

	var commandID = Utility.genGUID();
	var callbackID = Utility.genGUID();
	this.session.registerCallback(callbackID, callbackWrapper);
	
	var params = {
		commandID: commandID,
		nodeIDs: CvtForJson.cvtNodeArray(nodes),
		callbackID: callbackID
	};
    this.session.request(this.objectID, "createDetachCommand", params);
	
	return new Command(commandID);
};

/**
 * 创建分离Command
 * 将子节点从父节点上分离,分离后会重新创建一个新的节点代表分离的节点回送给用户
 * 并把新的节点作为parentsNode中的每一个node的孩子,目的是防止之后再添加回场景中时发生闪烁
 * 
 * @param {object} 		options					需要分离的节点和分离后节点的父节点
 * @param {Node[]}     	options.nodes 			需要分离的节点
 * @param {Node[]}     	[options.parentNodes] 	分离后节点的父节点
 * @param {Function} 	callback				返回分离结果
 * @param {Error}       callback.error 			返回错误
 * @param {Node[]}		callback.nodes  		返回分离后的节点
 *
 * @return {View3D.Command}
 */
DrawingRootNode.prototype.createDetachToCommand = function (options, callback) {
	ParamValidation.checkIsTypeArray(options.nodes, Node, "The  type of nodes must be 'Node Array' and valid!");
	Condicio.checkIsFunction(callback, "The type of callback must be 'Function'!");
	
	var callbackWrapper = function (error, result) {
		if (!error) {
			var nodes = result.nodes;

			var tempNodes = [];
			for (var i = 0; i < nodes.length ; ++i) {
				if (nodes[i].nodeID !== "")
					tempNodes.push(new Node(this.session, nodes[i].nodeID, nodes[i].name));
				else
					tempNodes.push(null); // 没找到给一个空
			}

			callback(error, tempNodes);
		}
		else {
			callback(error, null);
		}
	};

	var commandID = Utility.genGUID();
	var callbackID = Utility.genGUID();
	this.session.registerCallback(callbackID, callbackWrapper);
	
	var params = {
		commandID: commandID,
		nodeIDs: CvtForJson.cvtNodeArray(options.nodes),
		callbackID: callbackID
	};

	if(options.parentNodes !== undefined){
		ParamValidation.checkIsTypeArray(options.parentNodes, Node, "The  type of nodes must be 'Node Array' and valid!");
		params.parentNodeIDs = CvtForJson.cvtNodeArray(options.parentNodes);
	}
	else{
		params.parentNodeIDs = [];
	}

    this.session.request(this.objectID, "createDetachCommand", params);
	
	return new Command(commandID);
};

/**
 * 创建分离恢复Command
 * 将分离后的子节点重新加入到父节点下
 * 
 * @param {Node[]}     	nodes 			已从Drawing下分离的节点
 * @param {Function} 	callback		返回恢复结果
 * @param {Error}       callback.error 	返回错误
 *
 * @return {View3D.Command}
 */
DrawingRootNode.prototype.createUndetachCommand = function (nodes, callback) {
	ParamValidation.checkIsTypeArray(nodes, Node, "The  type of nodes must be 'Node Array' and valid!");
	
	var callbackWrapper = function (error, result) {
		callback(error);
	}
	
	var commandID = Utility.genGUID();
	var callbackID = Utility.genGUID();
	this.session.registerCallback(callbackID, callbackWrapper);
	
	var params = {
		commandID: commandID,
		nodeIDs: CvtForJson.cvtNodeArray(nodes),	
		callbackID: callbackID
	};
    this.session.request(this.objectID, "createUndetachCommand", params);
	
	return new Command(commandID);
};

module.exports = DrawingRootNode;