"use strict";

var _ = require("lodash");

var Node = require("./Node.js"),
    Interaction = require("./Interaction.js"),
    Utility = require("../Utility.js"),
	CvtForJson = require("../CvtForJson.js"),
	PointPickInteraction = require("./PointPickInteraction.js"),
	MouseHoverInteraction = require("./MouseHoverInteraction.js"),
	CompositeInteraction = require("./CompositeInteraction.js"),
	ParamValidation = require("../ParamValidation.js"),
	Style = require("./Style.js"),
	GLM = require("gl-matrix"),
	COLOR = require("color"),
	Condicio = require("condicio"),
	jQuery = require("jquery"),
	Tracker = require("./Tracker.js"),
	LineBasedRectTracker = require("./LineBasedRectTracker.js"),
	cvtToNodeArray = require("./CvtToNodeArray"),
	PickFilter = require("./Filter.js");
	

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

//解析点击结果
var analysePicked = function (picked, session) {
    var pickedArray = [];
    for (var i = 0; i < picked.length; ++i) {
        var pick = {};
        pick.position = CvtForJson.cvtToVec3(picked[i].position);
        pick.normal = CvtForJson.cvtToVec3(picked[i].normal);
        pick.nodePath = cvtToNodeArray(picked[i].nodePath, session);
		
        pickedArray.push(pick);
    }
    return pickedArray;
};

/**
 * 创建鼠标左键/右键点选操作交互
 * 需要注意的点是:单击pickHandler只会回复一次交互结果;双击的情况下会先回一次单击交互结果再回一次双击交互结果
 * @localdoc
 * @param {Function} 	pickHandler				        	当选择了一个点,则触发此回调
 * @param {Error} 	 	pickHandler.err 			        交互过程中发生错误传出错误
 * @param {Object}      pickHandler.msg                    	交互结果信息
 * @param {Number} 		pickHandler.msg.button             	标识鼠标左键/右键与触发类型 0-左键单击  2-右键单击 3-左键双击
 * @param {vec2} 		pickHandler.msg.screenPosition	    鼠标点击位置屏幕坐标
 * @param {Object[]} 	pickHandler.msg.picked		        选中节点信息,按照被选中节点离屏幕的距离从近到远排序,如果没有选中节点,则返回空数组
 * @param {Node[]} 		pickHandler.msg.picked.nodePath    	选中的节点路径,即从被选中的节点到根节点的所有节点按序排列
 * @param {vec3} 		pickHandler.msg.picked.position    	点击到节点上的位置
 * @param {vec3} 		pickHandler.msg.picked.normal	    点击到位置的法向
 * @param {Object}      [option]                        	创建鼠标点击交互的参数
 * @param {PickFilter}  [option.pickFilter]             	点击结果过滤器
 * @param {Tracker}  	[option.tracker]             		交互过程中附带的tracker
 *
 * @return {View3D.Interaction}
 */
InteractionFactory.prototype.createPointPickInteraction = function (pickHandler, option) {
    Condicio.checkIsFunction(pickHandler, "The type of pickHandler-callback must be 'Function'!");
	var pickFilterID = "";
	var trackerID = "";
	if (!Condicio.isUndefined(option) && !Condicio.isUndefined(option.pickFilter))
		pickFilterID = option.pickFilter.objectID;
	if (!Condicio.isUndefined(option) && !Condicio.isUndefined(option.tracker))
		trackerID = option.tracker.objectID;

    var _this = this;
    var pickHandlerWrapper = function (error, result) {
        var picks = result.picked;
        //解析点击结果
        var picked = analysePicked(picks, _this.session);

        var msg = new Object();
        // 屏幕坐标
        msg.screenPos = CvtForJson.cvtToVec2(result.screenPos);
        // 选中节点信息
        msg.picked = picked;
        // 点击的鼠标键位
        msg.button = result.button;

        pickHandler(error, msg);
    }
	var pickHandlerID = Utility.genGUID();
	
    var interactionID = Utility.genGUID();
	var params = {
		interactionID: interactionID,
		pickHandlerID: pickHandlerID
	};
	if (pickFilterID !== "")
		params.pickFilterID = pickFilterID;
	if (trackerID !== "")
		params.trackerID = trackerID;
		
    this.session.request(this.objectID, "createPointPickInteraction", params);

    return new PointPickInteraction(interactionID, pickHandlerID, pickHandlerWrapper);
};

/**
 * 释放交互资源
 *
 * @param {Interaction[]} interactions 待释放的交互资源集合
 */
InteractionFactory.prototype.releaseInteraction = function (interactions) {
	ParamValidation.checkIsTypeArray(interactions, Interaction, "The type of Resources waiting release must be 'Interaction Array'");

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

    this.session.request(this.objectID, "releaseInteraction", { objectIDs: objectIDs });
};

/**
 * 创建鼠标悬停操作交互
 * 
 * @param {Function} 	hoverHandler                        当鼠标悬停或悬停结束都会触发此回调
 * @param {Error}       hoverHandler.err                    交互过程中失败
 * @param {Object}  	hoverHandler.msg                	鼠标悬停交互结果信息
 * @param {Number} 		hoverHandler.msg.mouseHoverState 	0:标识鼠标开始悬停,1:标识鼠标结束悬停
 * @param {Vec2} 		hoverHandler.msg.screenPosition     鼠标悬停时的屏幕坐标,结束悬停时坐标值无效
 * @param {Object[]} 	hoverHandler.msg.picked				参照{@link #createPointPickInteraction} picked的定义
 * @param {Object}      [option]                        	创建鼠标点击交互的参数
 * @param {PickFilter}  [option.pickFilter]             	点击结果过滤器
 * @param {Tracker}  	[option.tracker]             		交互过程中附带的tracker
 * @param {Number}		[option.hoverTime = 300]			鼠标悬停需要的时间(毫秒)
 *
 * @return {View3D.Interaction}
 */
InteractionFactory.prototype.createMouseHoverInteraction = function (hoverHandler, option) {
    Condicio.checkIsFunction(hoverHandler, "The type of hoverHandler-callback must be 'Function'!");
    var pickFilterID = "";
	var trackerID = "";
    if (!Condicio.isUndefined(option) && !Condicio.isUndefined(option.pickFilter))
        pickFilterID = option.pickFilter.objectID;
	if (!Condicio.isUndefined(option) && !Condicio.isUndefined(option.tracker))
		trackerID = option.tracker.objectID;
	
	var hoverTime = 300;
	if (!Condicio.isUndefined(option) && !Condicio.isUndefined(option.hoverTime))
        hoverTime = option.hoverTime;
	Condicio.checkArgument(hoverTime > 0, "param hoverTime must greater than 0!");
	
    var _this = this;
    var hoverHandlerWrapper = function (err, result) {
        var mouseHoverState = result.mouseHoverState;
        var screenPos = result.screenPos;
        var picks = result.picked;
        var pickedArray= analysePicked(picks, _this.session);
        var screenPosVec2 = new GLM.vec2.fromValues(screenPos[0], screenPos[1]);
        var msg = {
            screenPos       : screenPosVec2,
            picked          : pickedArray,
            mouseHoverState : mouseHoverState
        }
        hoverHandler(err, msg);
    };
    var hoverHandlerID = Utility.genGUID();
	
    var interactionID = Utility.genGUID();
	var params = {
		interactionID: interactionID,
		hoverHandlerID: hoverHandlerID,
		hoverTime: hoverTime
	};
    if (pickFilterID !== "")
        params.pickFilterID = pickFilterID;
    if (trackerID !== "")
		params.trackerID = trackerID;
	
    this.session.request(this.objectID, "createMouseHoverInteraction", params);

    return new MouseHoverInteraction(interactionID, hoverHandlerID, hoverHandlerWrapper);
};

/**
 * 创建混合式交互操作,满足可以开启多个交互的操作
 *
 * @param  {Interaction[]} interactions  交互的集合
 *
 * @return {View3D.Interaction}
 */
InteractionFactory.prototype.createCompositeInteraction = function (interactions) {
    ParamValidation.checkIsTypeArray(interactions, Interaction, "The type of interactions must be 'Interaction Array' and valid");
    Condicio.checkArgument(interactions.length != 0, "The number of interactions must`t be NULL!");

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

    var interactionID = Utility.genGUID();
	var params = {
		interactionID: interactionID,
		subInteractionIDs: interactionIDs
	};
    this.session.request(this.objectID, "createCompositeInteraction", params);

    return new CompositeInteraction(interactionID, interactions);
};

/**
 * 创建距离点的皮筋,包括动态变化的线和文字
 *
 * @param  	{vec3} 		startPt  				皮筋的起点
 * @param  	{Object} 	[style]  				绘制属性
 * @param  	{Object} 	[style.lineStyle]  		线属性,参照View3D.Style.LineStyle的定义
 * @param 	{Object}	[style.textFrameStyle]	文字属性,参照View3D.Style.TextFrameStyle的定义
 *
 * @return	{View3D.Tracker}
 */
InteractionFactory.prototype.createDistanceToPointTracker = function (startPt, style) {
	var defaultStyle = {
		lineStyle: Style.LineStyle,
		textFrameStyle: Style.TextFrameStyle
	};
	var newStyle = jQuery.extend(true, {}, defaultStyle, style);
	
	ParamValidation.checkIsVec3(startPt, "The type of startPt must be 'vec3'!");
	ParamValidation.checkIsLineStyle(newStyle.lineStyle);
	ParamValidation.checkIsTextFrameStyle(newStyle.textFrameStyle);
	
	newStyle.lineStyle.color = newStyle.lineStyle.color.rgbaArray();
	newStyle.textFrameStyle.text.color = newStyle.textFrameStyle.text.color.rgbaArray();
	newStyle.textFrameStyle.border.color = newStyle.textFrameStyle.border.color.rgbaArray();
	newStyle.textFrameStyle.text.backdropColor = newStyle.textFrameStyle.text.backdropColor.rgbaArray();
	newStyle.textFrameStyle.fillColor = newStyle.textFrameStyle.fillColor.rgbaArray();
	var startPtArray = CvtForJson.cvtVec3(startPt);
	
	var trackerID = Utility.genGUID();
	var params = {
		trackerID: trackerID,
		startPoint: startPtArray,
		style: newStyle
	};
	this.session.request(this.objectID, "createDistanceToPointTracker", params);
	
	return new Tracker(trackerID);
};

/**
 * 创建距离一个面的皮筋(跟随鼠标的一端会有一个点),包括动态变化的线和文字
 *
 * @param	{Object}	plane					面
 * @param  	{vec3} 		plane.point  			面上一个点
 * @param  	{vec3} 		plane.normal  			面的法线(垂直于面)	
 * @param  	{Object} 	[style]  				绘制属性
 * @param  	{Object} 	[style.lineStyle]  		线属性,参照View3D.Style.LineStyle的定义
 * @param 	{Object}	[style.textFrameStyle]	文字属性,参照View3D.Style.TextFrameStyle的定义
 * @param 	{Object}	[style.pointStyle]		点属性,参照View3D.Style.PointStyle
 *
 * @return	{View3D.Tracker}
 */
InteractionFactory.prototype.createDistanceToPlaneTracker = function (plane, style) {
	var defaultStyle = {
		lineStyle: Style.LineStyle,
		textFrameStyle: Style.TextFrameStyle,
		pointStyle: Style.PointStyle
	};
	var newStyle = jQuery.extend(true, {}, defaultStyle, style);
	
	ParamValidation.checkIsVec3(plane.point, "The type of plane.point must be 'vec3'!");
	ParamValidation.checkIsVec3(plane.normal, "The type of plane.normal must be 'vec3'!");
	Condicio.checkArgument(GLM.vec3.length(plane.normal) > 0, "The plane.normal must be valid!");
	ParamValidation.checkIsLineStyle(newStyle.lineStyle);
	ParamValidation.checkIsTextFrameStyle(newStyle.textFrameStyle);
	ParamValidation.checkIsPointStyle(newStyle.pointStyle);
	
	newStyle.lineStyle.color = newStyle.lineStyle.color.rgbaArray();
	newStyle.textFrameStyle.text.color = newStyle.textFrameStyle.text.color.rgbaArray();
	newStyle.textFrameStyle.border.color = newStyle.textFrameStyle.border.color.rgbaArray();
	newStyle.textFrameStyle.text.backdropColor = newStyle.textFrameStyle.text.backdropColor.rgbaArray();
	newStyle.textFrameStyle.fillColor = newStyle.textFrameStyle.fillColor.rgbaArray();
	newStyle.pointStyle.color = newStyle.pointStyle.color.rgbaArray();
	
	var plane = {
		point: CvtForJson.cvtVec3(plane.point),
		normal: CvtForJson.cvtVec3(plane.normal)
	};
	
	var trackerID = Utility.genGUID();
	var params = {
		trackerID: trackerID,
		plane: plane,
		style: newStyle
	};
	this.session.request(this.objectID, "createDistanceToPlaneTracker", params);
	
	return new Tracker(trackerID);
};

/**
 * 创建跟随鼠标移动的小方框Tracker
 *
 * @return	{View3D.Tracker}		
 */
InteractionFactory.prototype.createFollowRectTracker = function () {
	var trackerID = Utility.genGUID();
	var params = {
		trackerID: trackerID
	};
	this.session.request(this.objectID, "createFollowRectTracker", params);
	return new Tracker(trackerID);
};

/**
 * 创建复合Tracker
 *
 * @param  	{Tracker[]} trackers tracker的集合
 *
 * @return	{View3D.Tracker}
 */
InteractionFactory.prototype.createCompositeTracker = function (trackers) {
	ParamValidation.checkIsTypeArray(trackers, Tracker, "The type of trackers must be 'Tracker Array' and valid");
    Condicio.checkArgument(trackers.length != 0, "The number of trackers must`t be NULL!");

    var trackerIDs = [];
    for (var i = 0; i < trackers.length; ++i) {
        trackerIDs.push(trackers[i].objectID);
    }
	
	var trackerID = Utility.genGUID();
	var params = {
		trackerID: trackerID,
		subTrackerIDs: trackerIDs
	};
	this.session.request(this.objectID, "createCompositeTracker", params);
	
	return new Tracker(trackerID);
};

/**
 * 创建垂直距离水平距离Tracker
 *
 * @param  	{vec3} 		startPt  				皮筋的起点
 * @param  	{Object} 	[style]  				绘制属性
 * @param  	{Object} 	[style.lineStyle]  		线属性,参照View3D.Style.LineStyle的定义
 * @param 	{Object}	[style.textFrameStyle]	文字属性,参照View3D.Style.TextFrameStyle的定义
 *
 * @return	{View3D.Tracker}
 */
InteractionFactory.prototype.createVHDistanceTracker = function (startPt, style) {
	var defaultStyle = {
		lineStyle: Style.LineStyle,
		textFrameStyle: Style.TextFrameStyle
	};
	var newStyle = jQuery.extend(true, {}, defaultStyle, style);
	
	ParamValidation.checkIsVec3(startPt);
	ParamValidation.checkIsLineStyle(newStyle.lineStyle);
	ParamValidation.checkIsTextFrameStyle(newStyle.textFrameStyle);
	
	newStyle.lineStyle.color = newStyle.lineStyle.color.rgbaArray();
	newStyle.textFrameStyle.text.color = newStyle.textFrameStyle.text.color.rgbaArray();
	newStyle.textFrameStyle.border.color = newStyle.textFrameStyle.border.color.rgbaArray();
	newStyle.textFrameStyle.text.backdropColor = newStyle.textFrameStyle.text.backdropColor.rgbaArray();
	newStyle.textFrameStyle.fillColor = newStyle.textFrameStyle.fillColor.rgbaArray();
	var startPtArray = CvtForJson.cvtVec3(startPt);
	
	var trackerID = Utility.genGUID();
	var params = {
		trackerID: trackerID,
		startPoint: startPtArray,
		style: newStyle
	};
	this.session.request(this.objectID, "createVHDistanceTracker", params);
	
	return new Tracker(trackerID);
};

/**
 * 创建绘制矩形Tracker
 * 把一个线段沿垂直线段方向拉伸形成一个矩形
 * 
 * @param	{Object}	baseLine				矩形的起始边
 * @param  	{vec3} 		baseLine.startPt  		矩形起始边的起点
 * @param  	{vec3} 		baseLine.endPt  		矩形起始边的终点
 * @param  	{Object} 	[style]  				绘制属性
 * @param  	{Object} 	[style.lineStyle]  		线属性,参照View3D.Style.LineStyle的定义
 * @param 	{Object}	[style.textFrameStyle]	文字属性,参照View3D.Style.TextFrameStyle的定义
 *
 * @return	{View3D.LineBasedRectTracker}
 */
InteractionFactory.prototype.createLineBasedRectTracker = function (baseLine, style) {
	Condicio.checkIsObject(baseLine, "The type of baseLine must be 'Object'!");
	ParamValidation.checkIsVec3(baseLine.startPt);
	ParamValidation.checkIsVec3(baseLine.endPt);
	
	var defaultStyle = {
		lineStyle: Style.LineStyle,
		textFrameStyle: Style.TextFrameStyle
	};
	var newStyle = jQuery.extend(true, {}, defaultStyle, style);
	ParamValidation.checkIsLineStyle(newStyle.lineStyle);
	ParamValidation.checkIsTextFrameStyle(newStyle.textFrameStyle);
	
	newStyle.lineStyle.color = newStyle.lineStyle.color.rgbaArray();
	newStyle.textFrameStyle.text.color = newStyle.textFrameStyle.text.color.rgbaArray();
	newStyle.textFrameStyle.text.backdropColor = newStyle.textFrameStyle.text.backdropColor.rgbaArray();
	newStyle.textFrameStyle.border.color = newStyle.textFrameStyle.border.color.rgbaArray();
	newStyle.textFrameStyle.fillColor = newStyle.textFrameStyle.fillColor.rgbaArray();
	
	var startPtArray = CvtForJson.cvtVec3(baseLine.startPt);
	var endPtArray = CvtForJson.cvtVec3(baseLine.endPt);
	
	var trackerID = Utility.genGUID();
	var params = {
		trackerID: trackerID,
		lineStartPoint: startPtArray,
		lineEndPoint: endPtArray,
		style: newStyle
	};
	this.session.request(this.objectID, "createLineBasedRectTracker", params);
	
	return new LineBasedRectTracker(trackerID);
};

/**
 * 创建过滤刨切的点击过滤器
 *
 * @return {View3D.PickFilter}
 */
InteractionFactory.prototype.createClipedPickFilter = function () {
    var pickFilterID = Utility.genGUID();
	
    this.session.request(this.objectID, "createClipedPickFilter", { pickFilterID: pickFilterID });

    return new PickFilter(pickFilterID);
};

/**
 * 创建过滤掉点选结果中除第一个之外的其他结果的过滤器
 * 如果点选结果本身就是空的则不执行该过滤
 *
 * @return {View3D.PickFilter}
 */
InteractionFactory.prototype.createFrontResultFilter = function () {
    var pickFilterID = Utility.genGUID();
	
    this.session.request(this.objectID, "createFrontResultFilter", { pickFilterID: pickFilterID });

    return new PickFilter(pickFilterID);
};

/**
 * 创建过滤器链
 * 过滤器链中的过滤器会依次起作用
 *
 * @param  	{PickFilter[]} 	filters  子过滤器
 *
 * @return {View3D.PickFilter}
 */
InteractionFactory.prototype.createChainFilter = function (filters) {
    var pickFilterID = Utility.genGUID();
	
	ParamValidation.checkIsTypeArray(filters, PickFilter, "The type of filters must be 'PickFilter Array' and valid");
    Condicio.checkArgument(filters.length != 0, "The number of filters must`t be NULL!");

    var filterIDs = [];
    for (var i = 0; i < filters.length; ++i) {
		filterIDs.push(filters[i].objectID);
    }
	var params = {
		pickFilterID: pickFilterID,
		subFilterIDs: filterIDs
	};
	
    this.session.request(this.objectID, "createChainFilter", params);

    return new PickFilter(pickFilterID);
};

/**
 * 创建过滤掉没有命名的过滤器
 * 没有命名是指该点击结果的NodePath中所有的节点都没有命名
 *
 * @return {View3D.PickFilter}
 */
InteractionFactory.prototype.createNamedNodeFilter = function () {
    var pickFilterID = Utility.genGUID();
	
    this.session.request(this.objectID, "createNamedNodeFilter", { pickFilterID: pickFilterID });

    return new PickFilter(pickFilterID);
};

/**
 * 创建节点路径中包含特定节点的过滤器
 * 当一个点击结果的NodePath中包含指定的节点则该点击结果不被该过滤器过滤掉
 *
 * @param  	{Node[]} 	includeNodes  			指定的节点
 *
 * @return {View3D.PickFilter}
 */
InteractionFactory.prototype.createIncludeNodeFilter = function (includeNodes) {
	var nodeIDArray = CvtForJson.cvtNodeArray(includeNodes);
	
    var pickFilterID = Utility.genGUID();
	var params = {
		pickFilterID: pickFilterID,
		includeNodes: nodeIDArray
	};
    this.session.request(this.objectID, "createIncludeNodeFilter", params);

    return new PickFilter(pickFilterID);
};

/**
 * 创建过滤掉透明节点的过滤器					
 * 在点击结果中过滤掉透明度低于transparencyValue的节点
 *
 * @param 	{Object} 		options
 * @param  	{Number} 		[options.transparencyValue=0.5]  			透明度(范围0~1),0为全透明,1为不透明(值:0<=transparencyValue<=1)
 *
 * @return 	{View3D.PickFilter}
 */
InteractionFactory.prototype.createTransparencyNodeFilter = function (options) {
	if(Condicio.isUndefined(options))
		options = {};
	
	if(Condicio.isUndefined(options.transparencyValue))
		options.transparencyValue = 0.5;
	
	Condicio.checkIsNumber(options.transparencyValue, "The type of options.transparencyValue must be 'number'!");
	Condicio.checkArgument(options.transparencyValue >= 0 && options.transparencyValue <= 1, "The transparencyValue must: >= 0 && <= 1 !");
    var pickFilterID = Utility.genGUID();
	var params = {
		pickFilterID: pickFilterID,
		transparencyValue: options.transparencyValue
	};
	
    this.session.request(this.objectID, "createTransparencyNodeFilter", params);

    return new PickFilter(pickFilterID);
};

function vctRgbaArray(newStyle) {
	newStyle.lineStyle.color = newStyle.lineStyle.color.rgbaArray();
	newStyle.textFrameStyle.text.color = newStyle.textFrameStyle.text.color.rgbaArray();
	newStyle.textFrameStyle.border.color = newStyle.textFrameStyle.border.color.rgbaArray();
	newStyle.textFrameStyle.text.backdropColor = newStyle.textFrameStyle.text.backdropColor.rgbaArray();
	newStyle.textFrameStyle.fillColor = newStyle.textFrameStyle.fillColor.rgbaArray();
};

/**
 * 创建规则圆形的皮筋和该圆形直径的皮筋,包括动态变化的线和文字 (圆形皮筋与圆形直径皮筋只平行于xy平面,以startPt的z轴为准)
 *
 * @param  	{vec3} 		startPt  				皮筋的起点
 * @param  	{Object} 	[style]  				绘制属性
 * @param  	{Object} 	[style.lineStyle]  		线属性,参照View3D.Style.LineStyle的定义
 * @param 	{Object}	[style.textFrameStyle]	文字属性,参照View3D.Style.TextFrameStyle的定义
 * @param 	{Number}	[style.pointNum]		组成圆形皮筋的点数量(整数 3-65536)(默认值30) 
 * 
 * @return	{View3D.Tracker}
 */
InteractionFactory.prototype.createCircularTracker = function (startPt, style) {
	var defaultStyle = {
		lineStyle: Style.LineStyle,
		textFrameStyle: Style.TextFrameStyle
	};
	var newStyle = jQuery.extend(true, {}, defaultStyle, style);
	
	ParamValidation.checkIsVec3(startPt, "The type of startPt must be 'vec3'!");
	ParamValidation.checkIsLineStyle(newStyle.lineStyle);
	ParamValidation.checkIsTextFrameStyle(newStyle.textFrameStyle);

	if(style.pointNum === undefined) { style.pointNum = 30; }
	Condicio.checkIsNumber(style.pointNum, "option.pointNum must be a number");
	Condicio.checkArgument(style.pointNum >= 3 && style.pointNum <= 65536 && style.pointNum % 1 === 0, "option.pointNum must be a positive integer with values from 3 to 65536");

	vctRgbaArray(newStyle);

	var startPtArray = CvtForJson.cvtVec3(startPt);
	
	var trackerID = Utility.genGUID();
	var params = {
		trackerID: trackerID,
		startPoint: startPtArray,
		style: newStyle,
		pointNum: style.pointNum
	};
	this.session.request(this.objectID, "createCircularTracker", params);
	
	return new Tracker(trackerID);
};

module.exports = InteractionFactory;