/*
 * Kepler
 *
 */

import mesh 				from './mesh.js';

import entity 			from './entity.js';

import material 		from './material.js';

import sampler2D 		from './sampler2D.js';

import {math, vector2, vector3, matrix4} from './math.js';

/**
 * primitive object
**/
class linePrimitives{
	
	constructor( engine ) {

		this.indices;
	}
	
	
	
	/**
	 * set viewport
	 * @param {(viewport)} viewport
	**/
	setViewport( viewport ){
		
		this.viewport = viewport;
		this.gl = viewport.gl;
	}
	
	
	createLineCubeVertices = function(size, opt_matrix) {
	  var k = size / 2;

	  var vertices = [
		[-k, -k, -k],
		[+k, -k, -k],
		[-k, +k, -k],
		[+k, +k, -k],
		[-k, -k, +k],
		[+k, -k, +k],
		[-k, +k, +k],
		[+k, +k, +k]
	  ];

	  var indices = [
		[0, 1],
		[1, 3],
		[3, 2],
		[2, 0],
		[4, 5],
		[5, 7],
		[7, 6],
		[6, 4],
		[0, 4],
		[1, 5],
		[2, 6],
		[3, 7]
	  ];

		//var vertexInfo = o3djs.lineprimitives.createLineVertexInfo();
		//var positionStream = vertexInfo.addStream(3, o3djs.base.o3d.Stream.POSITION);
		var vertexArray = [];
		var indexArray = [];

		for (var v = 0; v < vertices.length; ++v) {
			vertexArray.push( vertices[v][0], vertices[v][1], vertices[v][2] );
		}

		for (var i = 0; i < indices.length; ++i) {
			indexArray.push(indices[i][0], indices[i][1]);
		}

		var newMesh = new mesh(this.engine);
		
		var normalData = [];
		var textureCoordData = [];
		
		newMesh.shape = 2;
		
		newMesh.createMeshFromArrays( indexArray, vertexArray, false, false );

		newMesh.draw_type = this.gl.LINES;
		
		
		return newMesh;
	}
	
	/**
	 * get frustum corner coordinates
	 * @param {(matrix4)} projection
	 * @param {(matrix4)} view
	 * @param {(matrix4)} world
	**/
	getFrustumCorners = function(projection, view, world) {
		
	var cornerVertices = [	[-1,1,1],[1,1,1],[1,-1,1],[-1,-1,1],
							[-1,1,-1],[1,1,-1],[1,-1,-1],[-1,-1,-1] 
							 ];	
		
		var viewClone = matrix4.copyMatrix(view);
		
		//viewClone = matrix4.setTranslation(viewClone, [0,0,0]);
		
		//if(world) {
			var viewProjection = matrix4.inverse( matrix4.composition(projection, viewClone) );
		//} else {
			//var viewProjection = matrix4.inverse( projection );
		//}
		
		var corners = [];

		for(var c =0; c < cornerVertices.length;c++)
		{
			var vert = cornerVertices[c];
			
			vert.push(0.0);
			
			vert = matrix4.transformPoint(viewProjection, vert);
			
			corners.push(vert);
		}
		
		return corners;
	};

	drawFrustum( projection, view, world ) {
		
		
		var corners = this.getFrustumCorners(projection, view, world);
		console.log("corners",corners);
		
		var vertexArray = [];
		var normalArray = [];
		var textureArray = [];
		var indexArray = [];
		
		for(var c = 0; c<corners.length; c++) {
			var corner = corners[c];
			
			vertexArray.push(corner[0], corner[1], corner[2]);
			normalArray.push(1,1,1);
			textureArray.push(0,c/10);
			
		}
		
	//var cornerVertices = [	[-1,1,-1],[1,1,-1],[1,-1,-1],[-1,-1,-1],  //near
	//						[-1,1,1],[1,1,1],[1,-1,1],[-1,-1,1] ];
							
							
		//[-1,1],[1,1],[1,-1],[-1,-1]
		indexArray.push(0, 1); // z=-1
		indexArray.push(1, 2);
		indexArray.push(2, 3);
		indexArray.push(3, 0);
		
		
		indexArray.push(5, 1);
		indexArray.push(6, 2);
		indexArray.push(4, 0);
		indexArray.push(7, 3);
		
		indexArray.push(4, 5);// z=1
		indexArray.push(5, 6);
		indexArray.push(6, 7);
		indexArray.push(7, 4);
		
		//console.log("cornersFlat", vertexArray);

		//console.log("corners", corners);
		
		var newMesh 				= new mesh(this.engine);
		
		newMesh.shape 			= 2;

		newMesh.draw_type 	= this.gl.LINES;
		
		newMesh.createMeshFromArrays( indexArray, vertexArray, normalArray, textureArray );

		return newMesh;
	}
	
	
	
	
	createLineRingVertices(radius, subdivisions, maxTexCoord, num) {
		


		var vertexArray = [];
		var normalArray = [];
		var textureArray = [];
		
		var indexArray = [];

		// Generate the individual vertices in our vertex buffer.
		for (var i = 0; i <= subdivisions; i++) {
			var theta = 2 * Math.PI * i / subdivisions;
			
			vertexArray.push(radius * Math.cos(theta), 0, radius * Math.sin(theta));
			normalArray.push(Math.cos(theta), 0, Math.sin(theta));
			textureArray.push(maxTexCoord * i / subdivisions);
		}

		// Connect the vertices by simple lines.
		for (var i = 0; i < subdivisions; i++) {
			indexArray.push(i, i+1);
		}

		var newMesh = new mesh(this.engine);
		
		newMesh.shape = 2;
		newMesh.draw_type = this.gl.LINES;
		
		newMesh.createMeshFromArrays( indexArray, vertexArray, normalArray, textureArray );

		

		return newMesh;
	};
	
	createLines(radius, subdivisions, maxTexCoord, num) {
		


		var vertexArray = [];
		var normalArray = [];
		var textureArray = [];
		
		var indexArray = [];

		// Generate the individual vertices in our vertex buffer.
		for (var i = 0; i <= subdivisions; i++) {
			var theta = 2 * Math.PI * i / subdivisions;
			
			vertexArray.push(radius * Math.cos(theta), 0, radius * Math.sin(theta));
			normalArray.push(Math.cos(theta), 0, Math.sin(theta));
			textureArray.push(maxTexCoord * i / subdivisions);
		}

		// Connect the vertices by simple lines.
		for (var i = 0; i < subdivisions; i++) {
			indexArray.push(i, i+1);
		}

		var newMesh = new mesh(this.engine);
		
		newMesh.shape = 2;
		newMesh.draw_type = this.gl.LINES;
		
		newMesh.createMeshFromArrays( indexArray, vertexArray, normalArray, textureArray );

		

		return newMesh;
	};
	
createLineSphere = function(
    pack,
    material,
    radius,
    subdivisionsAxis,
    subdivisionsHeight,
    opt_matrix) {
		
  var vertexInfo = o3djs.lineprimitives.createLineSphereVertices(
      radius,
      subdivisionsAxis,
      subdivisionsHeight,
      opt_matrix);

  return vertexInfo.createShape(pack, material);
};

/**
 * Creates ring vertices.
 * The ring is a circle in the XZ plane, centered at the origin.
 * The created ring has position, normal, and 1-D texcoord streams.
 * The normals point outwards from the center of the ring.
 * The texture coordinates are based on angle about the center.
 *
 * @param {number} radius Radius of the ring.
 * @param {number} subdivisions Number of steps around the ring.
 * @param {number} maxTexCoord 1-D texture coordinates will range from 0 to
 *     this value, based on angle about the center.
 * @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply all
 *     the vertices.
 * @return {!o3djs.lineprimitives.LineVertexInfo} The created ring vertices.
 */
createRotationRingVertices(
    radius,
    subdivisions,
    maxTexCoord,
	length) {
		
  if (subdivisions < 3) {
     alert('subdivisions must be >= 3');
  }

		var vertexArray = [];
		var normalArray = [];
		var textureArray = [];
		
		var indexArray = [];

  // Generate the individual vertices in our vertex buffer.
  for (var i = 0; i <= subdivisions; i++) {
    var theta = length * 0.5 * Math.PI * i / subdivisions;

	var theta2 = Math.PI * i + 1 / subdivisions;
	
	var outerRadius = radius+1;
	
	//var outer_ring = new vector3(outerRadius * Math.cos(theta), 0, outerRadius * Math.sin(theta));
	//var outer_ring = new vector3(radiusRadius * Math.cos(theta), 0, radiusRadius * Math.sin(theta));
	

	
	if(i%2 == 0) {
		//outer ring
		vertexArray.push(outerRadius * Math.cos(theta), 0, outerRadius * Math.sin(theta));
		//inner ring
		vertexArray.push(radius * Math.cos(theta), 0, radius * Math.sin(theta));
		//outer ring
		//vertexArray.push(outerRadius * Math.cos(theta2), 0, outerRadius * Math.sin(theta2));
		
	} else {
		//vertexArray.push(radius * Math.cos(theta), 0, radius * Math.sin(theta));
		
		//vertexArray.push(outerRadius * Math.cos(theta), 0, outerRadius * Math.sin(theta));
		
		//vertexArray.push(radius * Math.cos(theta2), 0, radius * Math.sin(theta2));
	}
  }

  
  // Connect the vertices by simple lines.
  for (var i = 0; i < subdivisions; i++) {
    indexArray.push(i, i+1, i+2);
  }

	var newMesh = new mesh(this.engine);
	
	//newMesh.shape = 3;
	//newMesh.draw_type = this.gl.LINES;
	
	newMesh.createMeshFromArrays( indexArray, vertexArray, false, false );

		
  

  return newMesh;
  
}

	
	getLine(triangleIndex) {
		  var indexIndex = triangleIndex * 3;
		  
		  return [this.indices[indexIndex + 0],
				  this.indices[indexIndex + 1],
				  this.indices[indexIndex + 2]];
				  
	}
	
	setLine = function(lineIndex, index1, index2) {
	  var indexIndex = lineIndex * 2;
	  
	  this.indices[indexIndex + 0] = index1;
	  this.indices[indexIndex + 1] = index2;
	}
	
	/**
	 * Adds a line.
	 * @param {number} index1 The index of the first vertex of the line.
	 * @param {number} index2 The index of the second vertex of the line.
	 */
	addLine(index1, index2) {
	  this.indices.push(index1, index2);
	};
	
	numLines() {
	  return this.indices.length / 2;
	}
	
	
}

export {linePrimitives as default};