var Material = function (temp, meshes, set, scene) {

    var mat = this.Shaders[temp](set, scene,this);
    for (var ms in meshes) {
        ms = meshes[ms];
        ms.mesh.material = mat;


    }

    return mat;
};

var initEvents = function (sp,ind,fun) {
    sp.actionManager = new BABYLON.ActionManager(scene);
    sp.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPointerOverTrigger,
        function (ev) { 
            sp.material.flagUp(1);
        }));
    sp.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPointerOutTrigger,
        function (ev) {
            sp.material.flagDown(1);
        }));

    sp.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger,
        function (ev) {

            if (event.button == 2) {
                tabMatWind.go(0); currMeshInd = -1; meshSelect();
            }
            else fun(ind);
        })); 
     
    sp.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnRightPickTrigger,
            function (ev) {
               
            }));
}

var currMatItem = -1;

var iPBRTemplate = {
    alb: { r: 1., g: 0., b: 0. },
    albMap: '',
    uv: null,
    customUv: null
};

Material.prototype = {
    Extend: {
        Hover: function (me) {

            me = me.Reference(1)
                .InLine(' float iLen = min(1.,pow(max(max(sin(pos.x*1251.5+tan(pos.y*1256.2))*sin(pos.y*1345.5+tan(pos.z*1256.2)) , \
                                                sin(pos.z*132.5+tan(pos.y*1256.2))*sin(pos.y*1545.5+tan(pos.x*1256.2)) ),   \
                                                sin(pos.x*1342.5+tan(pos.z*1256.2))*sin(pos.z*1435.5+tan(pos.y*1256.2)) ),3.))-0.05;')
                .InLine('result.xyz = result.xyz *0.99; ')
                .Event(1, BABYLONX.Helper()
                .InLine('result.xyz = (result.xyz-0.01)*1.015;')
                .Build()
            ).Event(2, BABYLONX.Helper()
                .InLine('result.xyz = length(result.xyz)*vec3(1.,0.7,0.)*0.7+0.3*iLen ;')
                .Build()
            ).Event(4, BABYLONX.Helper()
                .InLine('result.w = iLen;')
                .Event(3, BABYLONX.Helper()
                    .InLine('result  = vec4(result_1.xyz,1.);')
                    .Back('discard;').Build()
                ).Back('').InLine('if(result.w<0.9)discard;else if(result.w<1.0) result.xyz = vec3(0.4,0.2,0.08);').Build()
            );
            return me;
        }
    },
    Shaders: {
        Default: function (set, scene, th) {

            set = def(set, {});

            return new BABYLONX.ShaderBuilder()

                .Solid({ r: 0.15 + Math.random(new Date().getMilliseconds())*0.15, g: 0.16, b: 0.2 })
                .Light({ direction: 'vec3(10000.)',normal:BABYLONX.Normals.Flat, phonge: 0.5, specular: 0.5 })
                .Light({ direction: 'vec3(-10000.)', normal: BABYLONX.Normals.Flat, phonge: 0.5, darkModeColor: true, color: { r: 0., g: 0., b: 0. }, specular: 0.5 })
                .Light({ direction: 'camera', normal: BABYLONX.Normals.Flat, phonge: 0.5,   specular: 1. })
                .Func(function (me) {

                    me.Setting.FragmentWorld = true; 
                    return me;
                })
                .Func(th.Extend.Hover)
                .BuildMaterial(scene);
        },
        PBRMatReadeSetting: function (set) {
               if (first('.imgUploader_alb_' + currMatItem)) {
                   set.albMap = (first('.imgUploader_alb_' + currMatItem + ' > img ')).src;
                   set.ambMap = (first('.imgUploader_amb_' + currMatItem + ' > img ')).src;
                   set.rugMap = (first('.imgUploader_rug_' + currMatItem + ' > img ')).src;
                   set.ref = (first('.PBRref' + currMatItem + '  .result ')).innerText.trim().valueOf() * 0.01;
                   set.rug = (first('.PBRrug' + currMatItem + '  .result ')).innerText.trim().valueOf() * 0.01;
                   set.uv.u = (first('.PBRMatCtl' + currMatItem + '  .tile_x ')).value.valueOf() * 1;
                   set.uv.v = (first('.PBRMatCtl' + currMatItem + '  .tile_y ')).value.valueOf() * 1;
            }
            console.log(set);
            return set;
        },
        PBRTemplate: function (set, scene,th) {

            set = def(set, {});

            set.alb = def(set.alb, { r: 1., g: 0., b: 0. });
            set.albMap = def(set.albMap, '');
            set.ambMap = def(set.ambMap, '');
            set.rugMap = def(set.rugMap, '');
            set.uv = def(set.uv, { u: 1., v: 1., us: 0., vs: 0. });
            set =  th.Shaders.PBRMatReadeSetting(set);
            set.customUv = def(set.customUv, 'vec2(vuv*vec2(float(' + set.uv.u + ') , float(' + set.uv.v + '))+vec2(float(' + set.uv.us + ') , float(' + set.uv.vs + ')) )');
            var ik = 0;
            var reflectPart = function (ref, nrm, scale, brk, x, y, z, bias) {
                ik++;
                return 'vec3 new_nrm' + ik + ' = ' + nrm + ';\
                vec3 vr'+ ik + ' = normalize( refract(  normalize(camera -pos*3.141592*length(camera- pos)*float(' + (scale)
                    + '))  ,  new_nrm' + ik + ', float(' +  (brk) + ')) ); \
                float y'+ ik + '= .5+  - atan( float(' + (z) + ')*vr' + ik + '.z,    float(' + (x) + ')*vr' + ik + '.x ) / (2.*3.141592);\
                float p'+ ik + '= 0.5  - atan( float(' +  (y) + ')*vr' + ik + '.y, length( vr' + ik + '.xz ) ) / ( 3.141592);\
                result = texture(  '+ ref + ', vec2( y' + ik + ', p' + ik + ') ,float(' + (bias) + ') );\
                ';
            };

            return new BABYLONX.ShaderBuilder()

                .Map({ path: '/images/env1.jpg' })
                .Solid(set.alb)
                .Func(function (me) {

                    me.Setting.FragmentWorld = true;
                    me = me.InLine('vec3 alb = vec3(0.);vec3 amb = vec3(0.);vec3 rug = vec3(0.);vec3 ref;');
                    if (set.albMap != '')
                    me = me.Map({ path: set.albMap, uv: set.customUv }).InLine('alb = result.xyz;');

                    if (set.ambMap != '')
                        me = me.Map({ path: set.ambMap }).InLine('amb = result.xyz;');
                    else me = me.InLine('amb = vec3(1.);');
                    if (set.rugMap != '')
                        me = me.Map({ path: set.rugMap, uv: set.customUv }).InLine('rug = result.xyz;');
                    else me = me.InLine('rug = vec3(0.);');
                    me = me.InLine('rug =1.-rug;');


                    me = me
                        .InLine(reflectPart(
                            'txtRef_0', 'nrm'
                            , 0.002 , 1, 1., 1., 1., '0.+rug.x*15.*float('+set.rug+')'))
                        .InLine('ref = result.xyz;');


                    me = me.InLine(`
                float rg =  (1.-float(` + set.ref + `) );
                 result = vec4(rg*alb 
                          + vec3((1.-rg)*ref*float(` + set.ref + `)),1.);

                    result.xyz *= amb;
                    `);

                    return me;
                })
                .Func(th.Extend.Hover)
                .BuildMaterial(scene);
        }
    }


}


