"use strict";
var Condicio = require("condicio"),
	COLOR = require("color"),
	Matrix = require("gl-matrix");

/**
 * @ignore
 * 参数判断
 */
var ParamValidation = {	
	checkIsLineStyle: function(lineStyle) {
		Condicio.checkIsObject(lineStyle, "The type of lineStyle must be 'Object'!");
		Condicio.checkIsNumber(lineStyle.width, "The type of lineStyle.width must be 'Number'!");
		//Condicio.checkIsType(lineStyle.color, COLOR, "The type of lineStyle.color must be 'COLOR'!");
		Condicio.checkIsString(lineStyle.type, "The type of lineStyle.type must be 'String'!");
		Condicio.checkArgument(lineStyle.type === 'solid' || lineStyle.type === 'stipple', "The type of lineStyle.type must be valid");
	},
	
	checkIsPointStyle: function(pointStyle) {
		Condicio.checkIsObject(pointStyle, "The type of pointStyle must be 'Object'!");
		Condicio.checkIsNumber(pointStyle.size, "The type of pointStyle.size must be 'Number'!");
		//Condicio.checkIsType(pointStyle.color, COLOR, "The type of pointStyle.color must be 'COLOR'!");
	},
	
	checkIsBorderStyle: function(borderStyle) {
		Condicio.checkIsObject(borderStyle, "The type of borderStyle must be 'Object'!");
		Condicio.checkIsNumber(borderStyle.width, "The type of borderStyle.width must be 'Number'!");
		//Condicio.checkIsType(borderStyle.color, COLOR, "The type of borderStyle.color must be 'COLOR'!");
	},
	
	checkIsTextStyle: function(textStyle) {
		Condicio.checkIsObject(textStyle, "The type of textStyle must be 'Object'!");
		Condicio.checkIsNumber(textStyle.size, "The type of textStyle.size must be 'Number'!");
		Condicio.checkIsString(textStyle.alignment, "The type of textStyle.alignment must be 'String'!");
		//Condicio.checkIsType(textStyle.color, COLOR, "The type of textStyle.color must be 'COLOR'!");
		Condicio.checkArgument(textStyle.alignment !== 'left' || textStyle.alignment !== 'center' 
								|| textStyle.alignment !== 'right', "The textStyle.alignment muset be valid");
		Condicio.checkIsNumber(textStyle.lineSpacing, "The type of textStyle.lineSpacing must be 'Number'!");
	},
	
	checkIsTextFrameStyle: function(textFrameStyle) {
		Condicio.checkIsObject(textFrameStyle, "The type of textFrameStyle must be 'Object'!");
		this.checkIsBorderStyle(textFrameStyle.border);
		this.checkIsTextStyle(textFrameStyle.text);
		Condicio.checkIsNumber(textFrameStyle.padding, "param textFrameStyle.padding must be 'Number'");
		Condicio.checkIsString(textFrameStyle.shape, "param textFrameStyle.shape must be 'String'");
		Condicio.checkArgument(textFrameStyle.shape !== "rectangle" || textFrameStyle.shap !== "circle", "param textFrameStyle.shape must be valid!");
		//Condicio.checkIsType(textFrameStyle.fillColor, COLOR, "The type of textFrameStyle.fillColor must be 'COLOR'!");
	},
	
	checkIsTextLabelStyle: function(textLabelStyle) {
		Condicio.checkIsObject(textLabelStyle, "The type of textLabelStyle must be 'Object'!");
		this.checkIsTextFrameStyle(textLabelStyle.textFrame);
		this.checkIsLineStyle(textLabelStyle.pointer.line);
		Condicio.checkIsObject(textLabelStyle.connectPosition, "The type of textLabelStyle.connectPositio must be 'Object'!");
		Condicio.checkIsString(textLabelStyle.connectPosition.x, "The type of textLabelStyle.connectPosition.x must be 'String'!");
		Condicio.checkIsString(textLabelStyle.connectPosition.y, "The type of textLabelStyle.connectPosition.y must be 'String'!");
		Condicio.checkArgument(textLabelStyle.connectPosition.x === 'left' || textLabelStyle.connectPosition.x === 'center' 
								|| textLabelStyle.connectPosition.x === 'right', "The textLabelStyle.connectPosition.x muset be valid");
		Condicio.checkArgument(textLabelStyle.connectPosition.y !== 'bottom' || textLabelStyle.connectPosition.y !== 'middle' 
								|| textLabelStyle.connectPosition.y !== 'top', "The textLabelStyle.connectPosition.y muset be valid");					
	},
	
	checkIsLightStyle: function(lightStyle) {
		Condicio.checkIsObject(lightStyle, "The type of textLabelStyle must be 'Object'!");
		//Condicio.checkIsType(lightStyle.ambient, COLOR, "The type of lightStyle.ambient must be 'COLOR'!");
		//Condicio.checkIsType(lightStyle.diffuse, COLOR, "The type of lightStyle.diffuse must be 'COLOR'!");
		//Condicio.checkIsType(lightStyle.specular, COLOR, "The type of lightStyle.specular must be 'COLOR'!");
		this.checkIsVec4(lightStyle.position, "The type of lightStyle.position must be Vec4!");
		this.checkIsVec3(lightStyle.direction, "The type of lightStyle.direction must be Vec3!");
		Condicio.checkIsNumber(lightStyle.spotCutoff, "The type of lightStyle.spotCutoff must be 'Number'!");
		Condicio.checkIsNumber(lightStyle.range, "The type of lightStyle.range must be 'Number'!");
	},
	
	checkIsArcsStyle: function(arcsStyle) {
		Condicio.checkIsObject(arcsStyle, "The type of arcsStyle must be 'Object'!");
		//Condicio.checkIsType(arcsStyle.color, COLOR, "The type of arcsStyle.color must be 'COLOR'!");
		Condicio.checkIsNumber(arcsStyle.angle, "The type of arcsStyle.angle must be 'Number'!");
		Condicio.checkIsNumber(arcsStyle.width, "The type of arcsStyle.width must be 'Number'!");
		Condicio.checkArgument(arcsStyle.width > 0, "The ArcsStyle.width must > 0! ");
	},
	
	checkIsPidTextStyle: function(textStyle) {
		Condicio.checkIsObject(textStyle, "The type of textStyle must be 'Object'!");
		Condicio.checkIsNumber(textStyle.size, "The type of textStyle.size must be 'Number'!");
		Condicio.checkIsString(textStyle.fontName, "The type of textStyle.fontName must be 'String'!");
		//Condicio.checkIsType(textStyle.color, COLOR, "The type of textStyle.color must be 'COLOR'!");
	},
	
	checkIsPidTextFrameStyle: function(textFrameStyle) {
		Condicio.checkIsObject(textFrameStyle, "The type of textFrameStyle must be 'Object'!");
		this.checkIsPidTextStyle(textFrameStyle.text);
		Condicio.checkIsNumber(textFrameStyle.padding, "param textFrameStyle.padding must be 'Number'");
		//Condicio.checkIsType(textFrameStyle.backgroundFillColor, COLOR, "The type of textFrameStyle.backgroundFillColor must be 'COLOR'!");
		Condicio.checkIsBoolean(textFrameStyle.backgroundFill, "The type of textFrameStyle.backgroundFill must be 'boolean'!");
		Condicio.checkIsBoolean(textFrameStyle.showBorders, "The type of textFrameStyle.showBorders must be 'boolean'!");
	},
	
	checkIsAxisStyle: function(axisStyle) {
		Condicio.checkIsObject(axisStyle, "The type of textFrameStyle must be 'Object'!");
		Condicio.checkIsNumber(axisStyle.length, "param axisStyle.length must be 'Number'");
		Condicio.checkArgument(axisStyle.length > 0, "The axisStyle.length must > 0! ");
		Condicio.checkIsNumber(axisStyle.width, "param axisStyle.width must be 'Number'");
		Condicio.checkArgument(axisStyle.width > 0, "The axisStyle.width must > 0! ");
		Condicio.checkIsNumber(axisStyle.pickedRadius, "param axisStyle.pickedRadius must be 'Number'");
		Condicio.checkArgument(axisStyle.pickedRadius > 0, "The axisStyle.pickedRadius must > 0! ");
		//Condicio.checkIsType(axisStyle.color, COLOR, "The type of axisStyle.color must be 'COLOR'!");
		//Condicio.checkIsType(axisStyle.pickedColor, COLOR, "The type of axisStyle.pickedColor must be 'COLOR'!");
	},
	
	checkIsPolygonStyle: function(polygonStyle) {
		Condicio.checkIsObject(polygonStyle, "The type of polygonStyle must be 'Object'!");
		//Condicio.checkIsType(lineStyle.color, COLOR, "The type of lineStyle.color must be 'COLOR'!");
	},

	checkIsView3DConfig: function(view3DConfig) {

		Condicio.checkIsNumber(view3DConfig.maxFPS, "The type of maxFPS must be 'Number'!");
		Condicio.checkArgument(view3DConfig.maxFPS > 0, "The maxFPS must greater than 0");

		Condicio.checkIsNumber(view3DConfig.LODScale, "The type of LODScale must be 'Number'!");
		Condicio.checkArgument(view3DConfig.LODScale >= 0, "The LODScale must greater than 0 or");

		Condicio.checkIsNumber(view3DConfig.maxPagedLODNumber, "The type of maxPagedLODNumber must be 'Number'!");
		Condicio.checkArgument(view3DConfig.maxPagedLODNumber >= 0, "The maxPagedLODNumber must greater than 0");

		Condicio.checkIsBoolean(view3DConfig.enableTransparency, "The type of enableTransparency must be 'Boolean'!");
		Condicio.checkArgument(view3DConfig.enableTransparency == false || view3DConfig.enableTransparency == true, "The enableTransparency must false or true");

		Condicio.checkIsBoolean(view3DConfig.loadDurMoving, "The type of loadDurMoving must be 'Boolean'!");
		Condicio.checkArgument(view3DConfig.loadDurMoving == false || view3DConfig.loadDurMoving == true, "The loadDurMoving must false or true");
		
		Condicio.checkIsNumber(view3DConfig.maxFrameTime, "The type of maxFrameTime must be 'Number'!");
		Condicio.checkArgument(view3DConfig.maxFrameTime > 0, "The maxFrameTime must greater than 0");

		Condicio.checkIsNumber(view3DConfig.computeNearFarMode, "The type of computeNearFarMode must be 'Number'!");
		Condicio.checkArgument(view3DConfig.computeNearFarMode == 0 || view3DConfig.computeNearFarMode == 1, "The computeNearFarMode must 0 or 1");
	},


	checkIsParticalSystemStyle: function(particalSystemStyle) {

		this.checkIsVec3(particalSystemStyle.direction,"The type of style-direction must be 'vec3'" );
		this.checkIsVec3(particalSystemStyle.acceleration,"The type of style-acceleration must be 'vec3'" );
	
		Condicio.checkIsNumber(particalSystemStyle.angle, "The type of style-angle must be 'Number'!");

		Condicio.checkIsNumber(particalSystemStyle.size, "The type of style-size must be 'Number'!");
		Condicio.checkArgument(particalSystemStyle.size > 0, "The size must greater than 0");

		Condicio.checkIsNumber(particalSystemStyle.flowRate, "The type of style-flowRate must be 'Number'!");
		Condicio.checkArgument(particalSystemStyle.flowRate > 0, "The flowRate must greater than 0");

		Condicio.checkIsNumber(particalSystemStyle.lifeTime, "The type of style-lifeTime must be 'Number'!");
		Condicio.checkArgument(particalSystemStyle.lifeTime > 0, "The lifeTime must greater than 0");

		Condicio.checkIsString(particalSystemStyle.imageName, "The type of style-imageName must be 'String'!");

		if(particalSystemStyle.alphaInterpolations)
		{
			this.checkIsTypeArray(particalSystemStyle.alphaInterpolations, Object, "The type of style-alphaInterpolations must be 'Object Array'!");
		}
	},
	
	checkIsTypeArray: function(arr, type, message) { 
		Condicio.checkIsArray(arr, message);
		
		// 仅支持自定义的类和Number,Object和字符串类型
		for (var i=0; i<arr.length; ++i){
			if (type === String)
				Condicio.checkIsString(arr[i], message);
			else if (type === Number)
				Condicio.checkIsNumber(arr[i], message);
			else if (type === Object)
				Condicio.checkIsObject(arr[i], message);
			else
				Condicio.checkIsType(arr[i], type, message);
		}
	},

	checkIsVec2Array: function(vec2Array, message)
	{
		Condicio.checkIsArray(vec2Array, message);
	    for (var i=0; i<vec2Array.length; ++i){
	        Condicio.checkIsType(vec2Array[i], Matrix.glMatrix.ARRAY_TYPE, message);
	        Condicio.checkArgument(vec2Array[i].length === 2, message);
	    }
	},
	checkIsVec3Array: function(vec3Array, message)
	{
		Condicio.checkIsArray(vec3Array, message);
	    for (var i=0; i<vec3Array.length; ++i){
	        Condicio.checkIsType(vec3Array[i], Matrix.glMatrix.ARRAY_TYPE, message);
	        Condicio.checkArgument(vec3Array[i].length === 3, message);
	    }
	},
	checkIsVec4: function (vec4, message){
		Condicio.checkIsType(vec4, Matrix.glMatrix.ARRAY_TYPE, message);
		Condicio.checkArgument(vec4.length === 4, message);
	},
	checkIsVec3: function (vec3, message){
		Condicio.checkIsType(vec3, Matrix.glMatrix.ARRAY_TYPE, message);
		Condicio.checkArgument(vec3.length === 3, message);
	},
	
	checkIsVec2: function (vec2, message){
		Condicio.checkIsType(vec2, Matrix.glMatrix.ARRAY_TYPE, message);
		Condicio.checkArgument(vec2.length === 2, message);
	},
	
	checkIsMat4: function(mat, message) {
		Condicio.checkIsType(mat, Matrix.glMatrix.ARRAY_TYPE, message);
		Condicio.checkArgument(mat.length === 16, message);
	}
};

module.exports = ParamValidation;