//Base part
//Where all parts are inherited from
//Uses on main and sync

var PartBase = function(par){

    this.elapsed = 0;
    this.startTime = false;
    this.deltaFrame = 0;
    this.index = TDEMO.getId();
    this.postIndex = this.index+1;

    //console.log("Part renderer in index: ", this.index);

    var size = TDEMO.MAIN.getRendererSize();
    this.width = size[0];
    this.height = size[1];
    var aspect = this.width/this.height;

    var p = par || {};

    this.near = p.near !== undefined ? p.near : 0.1;
    this.far = p.far !== undefined ? p.far : 2000;

    this.scene = p.scene !== undefined ? p.scene : new THREE.Scene();
    this.camera = p.camera !== undefined ? p.camera : new THREE.PerspectiveCamera(50, aspect, this.near, this.far);
    this.lens = {
        fl : 10,
        fg : 35
    };

    if(this.camera.isPerspectiveCamera){
        this.camera.filmGauge = this.lens.fg;
        this.camera.setFocalLength(this.lens.fl);
    }
    this.camera.updateProjectionMatrix();

    this.scene.add(this.camera);

    this.renderPass = p.rendererPass !== undefined ? p.rendererPass : new THREE.RenderPass(this.scene, this.camera);
    this.renderPass.enabled = false;
    TDEMO.MAIN.getComposer().insertPass(this.renderPass, this.index);

    this.bloom = false;

    this.dof = false;
    this.dcopy = false;

    this.edge = false;

    this.vblur = false;
    this.hblur = false;
};

PartBase.prototype.setBloom = function(amount){
    if(this.bloom === false){

        this.bloom = new THREE.BloomPass(amount, 25, 4, this.width);
        this.bloom.renderToScreen = true;
        this.bloom.needsSwap = false;
        this.bloom.clear = false;
        TDEMO.MAIN.getComposer().insertPass(this.bloom, this.postIndex);
        ++this.postIndex;
        this.bloom.enabled = false;
    }
};

PartBase.prototype.setDoF = function(par){
    var p = par || {};
    var focus = p.focus !== undefined ? p.focus : 1.0;
    var width = p.width !== undefined ? p.width : this.width;
    var height = p.height !== undefined ? p.height : this.height;
    var maxblur = p.maxblur !== undefined ? p.maxblur : 1.0;
    var aperture = p.aperture !== undefined ? p.aperture : 0.025;

    if(this.dof === false){
        this.dof = new THREE.BokehPass(this.scene, this.camera, {
            focus : focus,
            maxblur: maxblur,
            aperture: aperture,
            width: width,
            height: height
        });
        this.dof.needsSwap = true;
        this.dof.renderToScreen = false;
        this.dof.clear = false;
        TDEMO.MAIN.getComposer().insertPass(this.dof, this.postIndex);
        ++this.postIndex;

        this.dcopy = new THREE.ShaderPass(THREE.CopyShader);
        TDEMO.MAIN.getComposer().insertPass(this.dcopy, this.postIndex);
        ++this.postIndex;

        this.dof.enabled = false;
        this.dcopy.enabled = false;
    }
};

PartBase.prototype.setEdgeDetection = function(){
    if(this.edge === false){
        this.edge = new THREE.ShaderPass( THREE.EdgeShader2 );
        this.edge.uniforms[ "resolution" ].value =  new THREE.Vector2(this.width, this.height);
        TDEMO.MAIN.getComposer().insertPass(this.edge, this.postIndex);
        ++this.postIndex;

        this.edge.enabled = false;
    }
};

PartBase.prototype.setHorizontalBlur = function(amount){
    if(this.hblur === false){
        this.hblur = new THREE.ShaderPass( THREE.HorizontalBlurShader );
        this.hblur.uniforms[ "h" ].value =  amount/this.width;
        TDEMO.MAIN.getComposer().insertPass(this.hblur, this.postIndex);
        ++this.postIndex;

        this.hblur.enabled = false;
    }
};

PartBase.prototype.setVerticalBlur = function(amount){
    if(this.vblur === false){
        this.vblur = new THREE.ShaderPass( THREE.VerticalBlurShader );
        this.vblur.uniforms[ "v" ].value = amount/this.height;
        TDEMO.MAIN.getComposer().insertPass(this.vblur, this.postIndex);
        ++this.postIndex;

        this.vblur.enabled = false;
    }
};

//prepare is called just before first rendering
PartBase.prototype.prepare = function(elapsedTime, rtt){
    this.startTime = elapsedTime;
    this.renderPass.enabled = true;

    if(this.bloom !== false){
        this.bloom.enabled = true;
        //console.log("Bloom enabled from part : ", this.index);
    }
    if(this.dof !== false){
        this.dof.enabled = true;
        this.dcopy.enabled = true;
        //console.log("DoF enabled from part : ", this.index);
    }
    if(this.edge !== false){
        this.edge.enabled = true;
        //console.log("Edge detection enabled from part : ", this.index);
    }
    if(this.hblur !== false){
        this.hblur.enabled = true;
        //console.log("Horizontal blur enabled from part : ", this.index);
    }
    if(this.vblur !== false){
        this.vblur.enabled = true;
        //console.log("Vertical blur enabled from part : ", this.index);
    }
};

PartBase.prototype.finish = function(){
    this.renderPass.enabled = false;
    TDEMO.MAIN.getRenderer().clearTarget();

    if(this.bloom !== false){
        this.bloom.enabled = false;
        //console.log("Bloom disabled from part : ", this.index);
    }
    if(this.dof !== false){
        this.dof.enabled = false;
        this.dcopy.enabled = false;
        //console.log("DoF disabled from part : ", this.index);
    }
    if(this.edge !== false){
        this.edge.enabled = false;
        //console.log("Edge detection disabled from part : ", this.index);
    }
    if(this.hblur !== false){
        this.hblur.enabled = false;
        //console.log("Horizontal blur disabled from part : ", this.index);
    }
    if(this.vblur !== false){
        this.vblur.enabled = false;
        //console.log("Vertical blur disabled from part : ", this.index);
    }
};

//rendering function for rendering the scene to framebuffer otherwise the scene is rendered just with the composer
PartBase.prototype.render = function(renderer, rtt){
    renderer.render(this.scene, this.camera, rtt);
};

//animation
PartBase.prototype.animate = function(elapsedTime, delta, animateCamera){
    if(this.startTime !== false){
        this.elapsed = elapsedTime-this.startTime;
    }
    else{
        this.elapsed = 0;
    }
    this.deltaFrame = delta;

    //Animating camera propertis
    this.near = TDEMO.SYNC.getNear();
    this.far = TDEMO.SYNC.getFar();


    this.camera.near = this.near;
    this.camera.far = this.far;

    if(this.camera.isPerspectiveCamera){
        this.lens = TDEMO.SYNC.getLens();
        this.camera.filmGauge = this.lens.fg;
        this.camera.setFocalLength(this.lens.fl);
    }
    this.camera.updateProjectionMatrix();


    //Animating camera position only when animateCamera is set to true
    if(animateCamera){
        var camp = TDEMO.SYNC.getCameraPosition();
        this.camera.position.x = camp.x;
        this.camera.position.y = camp.y;
        this.camera.position.z = camp.z;

        var camr = TDEMO.SYNC.getCameraRotation();
        this.camera.rotation.x = camr.x;
        this.camera.rotation.y = camr.y;
        this.camera.rotation.z = camr.z;
    }
};

//--------------------------------------------------
// PROTOTYPAL INHERITANCE FUNCTION
//--------------------------------------------------
PartBase.prototype.inheritance = function(){
    function PartBasePrototype(){};
    PartBasePrototype.prototype = this;
    var created = new PartBasePrototype();
    return created;
};
