// JavaScript source code
//Namespace
this.wideload = this.wideload || {};


(function () {
    var MasterRenderer = function (main,renderer, resolution) {
        this.parts = [];
        this.renderer = renderer;
        this.main = main;
        this.targetResolution = resolution;
        this.scene = new THREE.Scene();
        var width = this.main.resolution.width;
        var height = this.main.resolution.height;
       // this.singleCamera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 2000);
        this.singleCamera = new THREE.OrthographicCamera(-(width / 2), width / 2, (height / 2), -(height / 2));
        this.singleCamera.position.z = 1;
        this.plane = new THREE.Mesh(new THREE.PlaneGeometry(width, height),new THREE.MeshBasicMaterial({ color: 0xffff00}));
        this.plane.position.z = 0;
        this.scene.add(this.singleCamera);
        this.scene.add(this.plane);
        this.cameras = {};
    };

    var p = MasterRenderer.prototype;

	p.swapScreen = function(screen)
	{
		
	}
	
    p.playEffect = function(effect, screens , configuration)
    {
		var colUpdated = false;
        if(configuration.color != undefined && configuration.color != null){
            // color effect
            for(var x = 0; x < screens.length; ++x){
                var s = screens[x];
               // s.material.map = null;
                s.material.color.setHex(configuration.color.getHex());
                s.material.colorsNeedUpdate = true;
            }
            colUpdated = true;
			
        }
		if(configuration.forceColor != undefined && configuration.forceColor != null){
            // color effect
            for(var x = 0; x < screens.length; ++x){
                var s = screens[x];
				reset_uvs(s);
                s.material.map = null;
                s.material.color.setHex(configuration.forceColor.getHex());
                s.material.colorsNeedUpdate = true;
				s.material.needsUpdate = true;
            }
            return;	
        }
		
        var effectRT = effect.renderTarget;
        
        if(configuration.split){
            var resolution = this.getResolution(configuration.screens);
            var ux = 1/resolution.width;
            var uy = 1/resolution.height;

            var miny = 999;
            var maxy = 0;
            var minx = 999;
            var maxx = 0;

            //UV-mapping the meshes
            var orderedScreens = new Array();
            for(var i = 0; i < screens.length; ++i){
				reset_uvs(screens[i]);
                var x = screens[i].xSegment;
                var y = screens[i].ySegment;
                miny = miny < y ? miny : y;
                maxy = maxy > y ? maxy : y;
                minx = minx < x ? minx : x;
                maxx = maxx > x ? maxx : x;
            }
            //console.log(minx + " ," + miny)
            for(var i = 0; i < screens.length; ++i){
                var x = screens[i].xSegment;
                var y = screens[i].ySegment;
                change_uvs(screens[i],ux,uy,(maxx-x),(maxy-y));
                screens[i].material.map = effectRT;    
                screens[i].material.needsUpdate = true;
            }
            return;
            

            var minX, maxX, minY,maxY;
            minX = maxX = orderedScreens[0].inner[0].xSegment;
            minY = maxY = orderedScreens[0].inner[0].ySegment;
            for(var i = 0; i < orderedScreens.length; ++i){
                if(orderedScreens[i] == undefined){
                    break;
                }

                var s = orderedScreens[i].inner;
              //  console.log("drawing x-line: " + i + ", found screens: ");
                for(var j = 0; j < s.length; ++j){

                    if(s[j] == undefined){
                        break;
                    }
                    minx = s[j].xSegment < minX ? s[j].xSegment : minX;
                    minY = s[j].ySegment < minY ? s[j].ySegment : minY;
                    maxX = s[j].xSegment > maxX ? s[j].xSegment : maxX;
                    maxY = s[j].ySegment > maxY ? s[j].ySegment : maxY;

                }                
            }


            
            for(var i = 0; i < orderedScreens.length; ++i){
                if(orderedScreens[i] == undefined){
                    break;
                }

                var s = orderedScreens[i].inner;
              //  console.log("drawing x-line: " + i + ", found screens: ");
                for(var j = 0; j < s.length; ++j){

                    if(s[j] == undefined){
                        break;
                    }
                   // console.log("["+s[j].xSegment, + s[j].ySegment+"], offset: " + "[" + i+"," + j + "]");
                     //console.log("[" +i + "," + j +"] == " + "[" + s[j].xSegment + "," + s[j].ySegment + "]" );
                    //reset_uvs(s[j]);
                    var ox = minX - s[j].xSegment;
                    var oy = s[j].ySegment-minY ;//;Math.ceil(i/resolution.width);
                    change_uvs(s[j],ux,uy,ox,oy);
                    s[j].material.map = effectRT;    
                    s[j].material.needsUpdate = true;
                }                
            }
        }
        else 
        {
            for (var i = 0 ; i < screens.length; ++i) {
                
                    //change_uvs(screens[i],1,1,0,0);
					screens[i].material.map = effectRT;
                    screens[i].material.needsUpdate = true;
                    reset_uvs(screens[i]);                   
                
            }
        }
    }

    function reset_uvs(mesh){
        if(mesh.originalUvs != undefined){
            var uvs_orig = mesh.originalUvs[0];
            var faceuvs = mesh.geometry.faceVertexUvs[0];
            for ( var i = 0; i < faceuvs.length; i ++ ) {
                var uvs = faceuvs[ i ];
                for ( var j = 0; j < uvs.length; j ++ ) {
                    var uv = uvs[ j ];
                    var orig_uv = uvs_orig[i][j];
                    uv.x = orig_uv.x;
                    uv.y = orig_uv.y;
                }
            }

            mesh.geometry.uvsNeedUpdate = true;    
        }
        
    }


    function change_uvs( mesh, unitx, unity, offsetx, offsety ) {
        var faceVertexUvs = mesh.geometry.faceVertexUvs[ 0 ];
        if(mesh.originalUvs == undefined){
            mesh.originalUvs = [];
            mesh.originalUvs[0] = [];
            for ( var i = 0, il = faceVertexUvs.length; i < il; i ++ ) {

                var uv = faceVertexUvs[ i ], uvCopy = [];

                for ( var j = 0, jl = uv.length; j < jl; j ++ ) {

                    uvCopy.push( new THREE.Vector2( uv[ j ].x, uv[ j ].y ) );

                }

                mesh.originalUvs[ 0 ].push( uvCopy );

            }
        }

        for ( var i = 0; i < faceVertexUvs.length; i ++ ) {
            var uvs = faceVertexUvs[ i ];
            for ( var j = 0; j < uvs.length; j ++ ) {
                var uv = uvs[ j ];
                uv.x = ( uv.x + offsetx ) * unitx;
                uv.y = ( uv.y + offsety ) * unity;
            }
        }
        mesh.geometry.uvsNeedUpdate = true;
       // mesh.geometry.verticesNeedUpdate = true;
    }

    p.render = function (elapsedTime) {
        //Nothing to do here \o/
    }

    p.getResolution = function(screens){
        var minresolution = {x:screens[0][0], y:screens[0][1]};
        var maxresolution = {x:screens[0][0], y:screens[0][1]};
        for(var j = 0; j < screens.length;++j){
            var s = screens[j];
            if(s[0] > maxresolution.x){
                maxresolution.x = s[0];
            }
            if(s[0] < minresolution.x){
                minresolution.x = s[0];
            }
            if(s[1] > maxresolution.y){
                maxresolution.y = s[1];
            }
            if(s[1] < minresolution.y){
                minresolution.y = s[1];
            }
        }
        return {width:maxresolution.x-minresolution.x+1, height:maxresolution.y-minresolution.y+1};
    }

    //Expose
    wideload.MasterRenderer = MasterRenderer;
}())