"use strict";

var _ = require("lodash"),
	Roamer = require("./Roamer.js"),
	Utility = require("../Utility.js"),
	Matrix = require("gl-matrix"),
	CvtForJson = require("../CvtForJson.js"),
	ParamValidation = require("../ParamValidation.js"),
	Condicio = require("condicio"),
	jQuery = require("jquery");
	

/**
 * @class View3D.RoamerFactory
 * 提供创建不同{@link Roamer}的接口
 *
 * 应用不应该构建,应该通过{@link View3D}直接获取
 */
function RoamerFactory(session, objectID) {
    this.session = session;
    this.objectID = objectID;

};

/**
 * 创建自由浏览交互: FreeModeRoamer
 * 新增参数可自由为左右中键绑定不同的交互
 * 为兼容之前版本option.opMode将会保留两个版本,若用户给定了option.opMode则以下四个给定参数leftMouseButton、rightMouseButton、middleMouseButton、mouseWheel不会生效
 * 若用户未给任何参数则默认的交互模式为mode1,opMode不为mode1或mode2时默认mode1
 * 若左右中键不想绑定任何操作,则可以给空字符串;例如:option.mouseWheel = ""
 *
 * @param {Object}		[option] 						创建漫游交互的选项
 * @param {String}		[option.opMode = "mode1"]		交互模式
 *							- "mode1" 	鼠标左键拖动旋转、中间滚轮拖动平移、右键拖动缩放、滑动滚轮缩放
 *  						- "mode2"	鼠标左键拖动旋转、右键拖动平移、滑动滚轮缩放
 *
 * @param {String}		[option.leftMouseButtonOperation = "rotate"]  	鼠标左键拖动可绑定旋转(rotate)或平移(pan)或缩放(zoom)
 * @param {String}		[option.rightMouseButtonOperation = "zoom"] 	鼠标右键拖动可绑定旋转(rotate)或平移(pan)或缩放(zoom)
 * @param {String}		[option.middleMouseButtonOperation = "pan"] 	中间滚轮拖动可绑定旋转(rotate)或平移(pan)或缩放(zoom)
 * @param {String}		[option.mouseWheelOperation = "zoom"] 			滑动滚轮可绑定缩放(zoom),默认是zoom
 * @param {vec3[]}		[option.viewpointLimitation]					限制的可视范围(目前限制范围为Box)Box八个顶点
 *							(<a href="https://fulongtech.atlassian.net/wiki/spaces/RenderingTech/pages/83200479">详细请参考</a>)
 *							缺省时表示没有限制
 * @param {vec3}		[option.fixedRotationCenter]			固定旋转中心;当设置固定旋转中心后,漫游器会固定以该点为中心进行旋转。
 *							缺省时表示没有固定旋转中心,旋转中心会动态获取
 * 
 * @return {View3D.Roamer}
 */
RoamerFactory.prototype.createFreeModeRoamer = function (option) {
	var mode1 = {
		leftMouseButtonOperation : "rotate",
		rightMouseButtonOperation : "zoom",
		middleMouseButtonOperation : "pan",
		mouseWheelOperation : "zoom"
	};
	var mode2 = {
		leftMouseButtonOperation : "rotate",
		rightMouseButtonOperation : "pan",
		middleMouseButtonOperation : "",
		mouseWheelOperation : "zoom",
	}
	
	var newOption = mode1;// 默认mode1

	if(!Condicio.isUndefined(option)) {
		newOption = jQuery.extend({}, mode1, option);// 此处mode1与option相同的属性进行合并时,option会覆盖mode1

		if(!Condicio.isUndefined(option.opMode)) {
			if(option.opMode === "mode2") {
				newOption = jQuery.extend({}, option, mode2);
			}
			else {
				newOption = jQuery.extend({}, option, mode1);// 此处mode1会覆盖option
			}
		}
	} 

	
	Condicio.checkIsString(newOption.rightMouseButtonOperation, "The type of newOption.rightMouseButtonOperation must be 'string'");
	Condicio.checkIsString(newOption.leftMouseButtonOperation, "The type of newOption.leftMouseButtonOperation must be 'string'");
	Condicio.checkIsString(newOption.middleMouseButtonOperation, "The type of newOption.middleMouseButtonOperation must be 'string'");
	Condicio.checkIsString(newOption.mouseWheelOperation, "The type of newOption.mouseWheelOperation must be 'string'");
	
	var roamerID = Utility.genGUID();
	var params = {
		roamerID: roamerID,
		leftMBOperation : newOption.leftMouseButtonOperation,
		rightMBOperation : newOption.rightMouseButtonOperation,
		middleMBOperation : newOption.middleMouseButtonOperation,
		mouseWheelOperation : newOption.mouseWheelOperation
	};
	
	if (newOption.viewpointLimitation)
	{
		ParamValidation.checkIsVec3Array(newOption.viewpointLimitation
		, "The type of option.viewpointLimitation must be vec3 array and valid!");
		Condicio.checkArgument(newOption.viewpointLimitation.length === 8, "the length of option.opMode must be 8");
		params.viewPointLimitation = CvtForJson.cvtVec3Array(newOption.viewpointLimitation);
	}
	if (newOption.fixedRotationCenter)
	{
		ParamValidation.checkIsVec3(newOption.fixedRotationCenter
		, "The type of option.fixedRotationCenter must be vec3!");
		params.fixedRotationCenter = CvtForJson.cvtVec3(newOption.fixedRotationCenter);
	}
	
    this.session.request(this.objectID, "createFreeModeRoamer", params);

    return new Roamer(roamerID);
};

/**
 * 删除漫游交互
* @param {Roamer[]} roamers 	 存储待删除漫游交互的数组
*/
RoamerFactory.prototype.releaseRoamers = function (roamers) {
	ParamValidation.checkIsTypeArray(roamers, Roamer, "The type of Resources waiting release must be 'Roamers Array'");

	var roamerIDs = [];
    for (var i = 0; i < roamers.length; ++i) {
		roamerIDs.push(roamers[i].objectID);
    }

    this.session.request(this.objectID, "releaseRoamer", { roamerIDs: roamerIDs });
};

module.exports = RoamerFactory;