var _default_vert = require("../../Shaders/ccShader_Default_Vert.js");
var _default_vert_no_mvp = require("../../Shaders/ccShader_Default_Vert_noMVP.js");

cc.Class({
    extends: cc.Component,

    properties: {
        flagShader:"",
        frag_glsl:{
            default:"Effect10.fs.glsl",
            visible:false,
        },
    }, 

    start: function () {
        var self = this;
        var now = new Date();
        this.parameters={
            startTime:Date.now()-((now.getMinutes()+now.getDate())*3+now.getSeconds()*1273+now.getMilliseconds()*4315),
            time:0.0,
            resolution:{
                x:0.0,
                y:0.0
            },
        };
        this.parameters.resolution.x = ( this.node.getContentSize().width );
        this.parameters.resolution.y = ( this.node.getContentSize().height );

        cc.loader.loadRes(self.flagShader,function(err,txt){
            if(err){
                cc.log(err)
            }else{
                self.frag_glsl = txt;

                    self._use();

            }
        });
    },
    update:function(dt){
        if(this._program){
            this._program.use();
            this.updateGLUniform(dt)
        }
    },

    updateGLUniform:function(dt){
        var len=this.su.length>1?this.su[this.su.length-1]:0
        //另外一个脚本的属性更新
        for(var i=0;i<len;i++)
        {
            this.su[i*3+1]=this.node.objType.shaderUniform[this.su[i*3]]
        }        
        //这个脚本的属性更新
        //(Date.now() - this.parameters.startTime)/1000
        this.parameters.time +=dt;
        //uniform更新
        if(cc.sys.isNative){
            var glProgram_state = cc.GLProgramState.getOrCreateWithGLProgram(this._program);
            //这个脚本的属性
            glProgram_state.setUniformFloat( "iGlobalTime", this.parameters.time );   
            //那个脚本的属性
            for(var i=0;i<len;i++)
            {
                switch(this.su[i*3+2])
                {
                    case 1:
                        glProgram_state.setUniformFloat(this.su[i*3],this.su[i*3+1]);   
                    break;
                    case 2:
                        glProgram_state.setUniformVec2(this.su[i*3],this.su[i*3+1]);   
                    break;
                    case 3:
                        glProgram_state.setUniformVec3(this.su[i*3],this.su[i*3+1]);   
                    break;
                    case 4:
                        glProgram_state.setUniformVec4(this.su[i*3],this.su[i*3+1]);   
                    break;
                    default:
                        console.log("shader default "+this.node.name)
                    break;
                }
            } 

        }else{
            //这个脚本的属性
            this._program.setUniformLocationWith1f( this._time, this.parameters.time );
            //那个脚本的属性
            for(var i=0;i<len;i++)
            {
                switch(this.su[i*3+2])
                {
                    case 1:
                        this._program.setUniformLocationWith1f(this.su[i+3*len],this.su[i*3+1]);   
                    break;
                    case 2:
                        this._program.setUniformLocationWith2f(this.su[i+3*len],this.su[i*3+1].x,this.su[i*3+1].y);   
                    break;
                    case 3:
                        this._program.setUniformLocationWith3f(this.su[i+3*len],this.su[i*3+1].x,this.su[i*3+1].y,this.su[i*3+1].z);   
                    break;
                    case 4:
                        this._program.setUniformLocationWith4f(this.su[i+3*len],this.su[i*3+1].x,this.su[i*3+1].y,this.su[i*3+1].z,this.su[i*3+1].w);   
                    break;
                    default:
                        console.log("shader default "+this.node.name)
                    break;
                }
            }
        }
    },

    _use: function()
    {     
        //shader   
        if (cc.sys.isNative) {
            cc.log("use native GLProgram");
            this._program = new cc.GLProgram();
            this._program.initWithString(_default_vert_no_mvp, this.frag_glsl );

            this._program.addAttribute(cc.macro.ATTRIBUTE_NAME_POSITION, cc.macro.VERTEX_ATTRIB_POSITION);
            this._program.addAttribute(cc.macro.ATTRIBUTE_NAME_COLOR, cc.macro.VERTEX_ATTRIB_COLOR);
            this._program.addAttribute(cc.macro.ATTRIBUTE_NAME_TEX_COORD, cc.macro.VERTEX_ATTRIB_TEX_COORDS);

            this._program.link();
            this._program.updateUniforms();        
        }else{
            this._program = new cc.GLProgram();
            this._program.initWithVertexShaderByteArray(_default_vert, this.frag_glsl );
            
            this._program.addAttribute(cc.macro.ATTRIBUTE_NAME_POSITION, cc.macro.VERTEX_ATTRIB_POSITION);
            this._program.addAttribute(cc.macro.ATTRIBUTE_NAME_COLOR, cc.macro.VERTEX_ATTRIB_COLOR);
            this._program.addAttribute(cc.macro.ATTRIBUTE_NAME_TEX_COORD, cc.macro.VERTEX_ATTRIB_TEX_COORDS);

            this._program.link();
            this._program.updateUniforms();
            this._program.use();
        }     
        //其他脚本的变量
        //su[i*3]属性名,su[i*3+1]属性值,su[i*3+2]属性类型,su[i+3*key.length]非原生平台的uniformlocation
        this.su=[]
        if(this.node.objType&&this.node.objType.shaderUniform)
        {
            var uni=this.node.objType.shaderUniform
            var key=Object.keys(uni)
            for(var i=0;i<key.length;i++)
            {
                this.su[i*3]=key[i]
                this.su[i*3+1]=uni[key[i]]
                this.su[i*3+2]=typeof(this.su[i*3+1])=="number"?1:Object.keys(this.su[i*3+1]).length
                if(!cc.sys.isNative)
                {
                    this.su[i+3*key.length]=this._program.getUniformLocationForName(key[i*3]);
                }
            }
            this.su.push(key.length)
        }
        //这个脚本的变量
        if (!cc.sys.isNative) {
            this._resolution = this._program.getUniformLocationForName( "iResolution" );
            this._time = this._program.getUniformLocationForName( "iGlobalTime" ); 
            this._program.setUniformLocationWith2f( this._resolution, this.parameters.resolution.x,this.parameters.resolution.y);   
        }
        else
        {                        
            var glProgram_state = cc.GLProgramState.getOrCreateWithGLProgram(this._program);        
            glProgram_state.setUniformVec2( "iResolution", this.parameters.resolution);
        }
        //更新
        this.updateGLUniform(Math.random()*1000);
        //执行
        this.setProgram( this.node._sgNode ,this._program );
    },
    
    setProgram:function (node, program) {
        if (cc.sys.isNative) {
            var glProgram_state = cc.GLProgramState.getOrCreateWithGLProgram(program);
            node.setGLProgramState(glProgram_state);
        }else{
            node.setShaderProgram(program);    
        }        
    
        var children = node.children;
        if (!children)
            return;
    
        for (var i = 0; i < children.length; i++)
            this.setProgram(children[i], program);
    },

});
