@Override
  public void init() {

    clock = THREE.Clock();

    WIDTH = (int) getWindowInnerWidth();
    HEIGHT = (int) getWindowInnerHeight();

    windowHalfX = (int) (getWindowInnerWidth() / 2);
    windowHalfY = (int) (getWindowInnerHeight() / 2);

    FocusPanel container = createContainerPanel();

    // renderer
    renderer = THREE.WebGLRenderer(WebGLRendererParameter.create().antialias(true));
    renderer.setPixelRatio(GWTThreeUtils.getWindowDevicePixelRatio());
    renderer.setSize(WIDTH, HEIGHT);
    container.getElement().appendChild(renderer.getDomElement());

    renderer.getShadowMap().setEnabled(true); // renderer.shadowMap.enabled = true;
    renderer
        .getShadowMap()
        .setType(THREE.PCFSoftShadowMap); // renderer.shadowMap.type = THREE.PCFSoftShadowMap;

    //

    renderer.setGammaInput(true); // renderer.gammaInput = true;
    renderer.setGammaOutput(true); // renderer.gammaOutput = true;

    // scene
    scene = THREE.Scene();
    scene.setFog(THREE.Fog(0x00aaff, 1000, FAR));

    // camera
    camera = THREE.PerspectiveCamera(45, getWindowInnerWidth() / getWindowInnerHeight(), 2, FAR);
    camera.getPosition().set(500, 400, 1200);

    cubeCamera = THREE.CubeCamera(1, FAR, 128);
    scene.add(cubeCamera);

    Canvas x = Canvas.createIfSupported();
    Context2d xc = x.getContext2d();
    x.setSize(128 + "px", 128 + "px");

    xc.setFillStyle("#fff");
    xc.fillRect(0, 0, 128, 128);
    xc.setFillStyle("#000");
    xc.fillRect(0, 0, 64, 64);
    xc.setFillStyle("#999");
    xc.fillRect(32, 32, 32, 32);
    xc.setFillStyle("#000");
    xc.fillRect(64, 64, 64, 64);
    xc.setFillStyle("#555");
    xc.fillRect(96, 96, 32, 32);

    CanvasTexture texturePattern = THREE.CanvasTexture(x.getCanvasElement()); // var
    // texturePattern
    // =
    // new
    // THREE.CanvasTexture(
    // x
    // )
    texturePattern.setFormat(THREE.RGBFormat); // texturePattern.format =
    // THREE.RGBFormat;
    texturePattern.getRepeat().set(1000, 1000); // texturePattern.repeat.set(
    // 1000, 1000 );
    texturePattern.setWrapS(THREE.RepeatWrapping); // texturePattern.wrapS =
    // THREE.RepeatWrapping;
    texturePattern.setWrapT(THREE.RepeatWrapping); // texturePattern.wrapT =
    // THREE.RepeatWrapping;

    Texture textureSquares =
        ImageUtils.loadTexture("textures/patterns/bright_squares256.png"); // var
    // textureSquares
    // =
    // THREE.ImageUtils.loadTexture(
    // "textures/patterns/bright_squares256.png"
    // );
    textureSquares.getRepeat().set(50, 50); // textureSquares.repeat.set( 50,
    // 50 );
    textureSquares.setWrapS(THREE.RepeatWrapping); // textureSquares.wrapS =
    // textureSquares.wrapT
    // =
    // THREE.RepeatWrapping;
    textureSquares.setWrapT(THREE.RepeatWrapping);
    textureSquares.setMagFilter(THREE.NearestFilter); // textureSquares.magFilter
    // =
    // THREE.NearestFilter;
    textureSquares.setFormat(THREE.RGBFormat); // textureSquares.format =
    // THREE.RGBFormat;

    Texture textureNoiseColor = ImageUtils.loadTexture("textures/disturb.jpg"); // var
    // textureNoiseColor
    // =
    // THREE.ImageUtils.loadTexture(
    // "textures/disturb.jpg"
    // );
    textureNoiseColor.getRepeat().set(1, 1); // textureNoiseColor.repeat.set(
    // 1, 1 );
    textureNoiseColor.setWrapS(THREE.RepeatWrapping); // textureNoiseColor.wrapS
    // =
    // textureNoiseColor.wrapT
    // =
    // THREE.RepeatWrapping;
    textureNoiseColor.setWrapT(THREE.RepeatWrapping);
    textureNoiseColor.setFormat(THREE.RGBFormat); // textureNoiseColor.format
    // = THREE.RGBFormat;

    Texture textureLava = ImageUtils.loadTexture("textures/lava/lavatile.jpg"); // var
    // textureLava
    // =
    // THREE.ImageUtils.loadTexture(
    // "textures/lava/lavatile.jpg"
    // );
    textureLava.getRepeat().set(6, 2); // textureLava.repeat.set( 6, 2 );
    textureLava.setWrapS(THREE.RepeatWrapping); // textureLava.wrapS =
    // textureLava.wrapT =
    // THREE.RepeatWrapping;
    textureLava.setWrapT(THREE.RepeatWrapping);
    textureLava.setFormat(THREE.RGBFormat); // textureLava.format =
    // THREE.RGBFormat;

    String path = "textures/cube/SwedishRoyalCastle/"; // var path =
    // "textures/cube/SwedishRoyalCastle/";
    String format = ".jpg"; // var format = '.jpg';
    String[] urls = {
      path + "px" + format,
      path + "nx" + format,
      path + "py" + format,
      path + "ny" + format,
      path + "pz" + format,
      path + "nz" + format
    };
    ;

    Texture reflectionCube = ImageUtils.loadTextureCube(JavaScriptUtils.toArray(urls)); // var
    // reflectionCube
    // =
    // THREE.ImageUtils.loadTextureCube(
    // urls
    // );

    // ground

    MeshPhongMaterial groundMaterial =
        THREE.MeshPhongMaterial(
            GWTParamUtils.MeshPhongMaterial()
                .shininess(80)
                .color(0xffffff)
                .specular(0xffffff)
                .map(textureSquares)); // var groundMaterial = new
    // THREE.MeshPhongMaterial( {shininess:
    // 80,color: 0xffffff,specular:
    // 0xffffff,map: textureSquares} );
    PlaneBufferGeometry planeGeometry = THREE.PlaneBufferGeometry(100, 100); // var
    // planeGeometry
    // =
    // new
    // THREE.PlaneBufferGeometry(
    // 100,
    // 100
    // );

    Mesh ground = THREE.Mesh(planeGeometry, groundMaterial); // var ground =
    // new
    // THREE.Mesh(
    // planeGeometry,
    // groundMaterial
    // );
    ground.getPosition().set(0, 0, 0); // ground.position.set( 0, 0, 0 );
    ground.getRotation().setX(-Math.PI / 2); // ground.rotation.x = - Math.PI
    // / 2;
    ground.getScale().set(1000, 1000, 1000); // ground.scale.set( 1000, 1000,
    // 1000 );

    ground.setReceiveShadow(true); // ground.receiveShadow = true;

    scene.add(ground);

    // materials
    Shader shader = ShaderLib.cube();
    shader.uniforms().set("tCube", cubeCamera.getRenderTarget()); // shader.uniforms[
    // "tCube"
    // ].texture
    // =
    // cubeCamera.renderTarget;
    shader.uniforms().set("tFlip", 1); // shader.uniforms[ "tFlip" ].value =
    // 1;

    ShaderMaterial materialCube =
        THREE.ShaderMaterial(
            GWTParamUtils.ShaderMaterial()
                .fragmentShader(shader.fragmentShader())
                .vertexShader(shader.vertexShader())
                .uniforms(shader.uniforms())); // var
    // materialCube
    // =
    // new
    // THREE.ShaderMaterial(
    // {fragmentShader:
    // shader.fragmentShader,vertexShader:
    // shader.vertexShader,uniforms:
    // shader.uniforms}
    // );

    MeshPhongMaterial materialLambert =
        THREE.MeshPhongMaterial(
            GWTParamUtils.MeshPhongMaterial()
                .shininess(50)
                .color(0xffffff)
                .map(textureNoiseColor)); // var
    // materialLambert
    // =
    // new
    // THREE.MeshPhongMaterial(
    // {
    // shininess:
    // 50,
    // color:
    // 0xffffff,
    // map:
    // textureNoiseColor
    // }
    // );
    MeshPhongMaterial materialPhong =
        THREE.MeshPhongMaterial(
            GWTParamUtils.MeshPhongMaterial()
                .shininess(50)
                .color(0xffffff)
                .specular(0x999999)
                .map(textureLava)); // var materialPhong = new
    // THREE.MeshPhongMaterial( { shininess: 50,
    // color: 0xffffff, specular: 0x999999, map:
    // textureLava } );

    MeshPhongMaterial materialPhongCube =
        THREE.MeshPhongMaterial(
            GWTParamUtils.MeshPhongMaterial()
                .shininess(50)
                .color(0xffffff)
                .specular(0x999999)
                .envMap(cubeCamera.getRenderTarget().gwtCastTexture())); // var
    // materialPhongCube
    // = new
    // THREE.MeshPhongMaterial(
    // {
    // shininess:
    // 50,
    // color:
    // 0xffffff,
    // specular:
    // 0x999999,
    // envMap:
    // cubeCamera.renderTarget
    // } );
    // stats

    // object
    SphereGeometry sphereGeometry = THREE.SphereGeometry(100, 64, 32); // var
    // sphereGeometry
    // =
    // new
    // THREE.SphereGeometry(
    // 100,
    // 64,
    // 32
    // );
    TorusGeometry torusGeometry = THREE.TorusGeometry(240, 60, 32, 64); // var
    // torusGeometry
    // =
    // new
    // THREE.TorusGeometry(
    // 240,
    // 60,
    // 32,
    // 64
    // );
    BoxGeometry cubeGeometry = THREE.BoxGeometry(150, 150, 150); // var
    // cubeGeometry
    // = new
    // THREE.BoxGeometry(
    // 150, 150,
    // 150 );

    addObject(torusGeometry, materialPhong, 0, 100, 0, 0);
    addObject(cubeGeometry, materialLambert, 350, 75, 300, 0);
    mesh = addObject(sphereGeometry, materialPhongCube, 350, 100, -350, 0);

    BoxGeometry bigCube = THREE.BoxGeometry(50, 500, 50);
    BoxGeometry midCube = THREE.BoxGeometry(50, 200, 50);
    BoxGeometry smallCube = THREE.BoxGeometry(100, 100, 100);

    addObjectColor(bigCube, 0xff0000, -500, 250, 0, 0);
    addObjectColor(smallCube, 0xff0000, -500, 50, -150, 0);

    addObjectColor(midCube, 0x00ff00, 500, 100, 0, 0);
    addObjectColor(smallCube, 0x00ff00, 500, 50, -150, 0);

    addObjectColor(midCube, 0x0000ff, 0, 100, -500, 0);
    addObjectColor(smallCube, 0x0000ff, -150, 50, -500, 0);

    addObjectColor(midCube, 0xff00ff, 0, 100, 500, 0);
    addObjectColor(smallCube, 0xff00ff, -150, 50, 500, 0);

    addObjectColor(THREE.BoxGeometry(500, 10, 10), 0xffff00, 0, 600, 0, Math.PI / 4);
    addObjectColor(THREE.BoxGeometry(250, 10, 10), 0xffff00, 0, 600, 0, 0);

    addObjectColor(THREE.SphereGeometry(100, 32, 26), 0xffffff, -300, 100, 300, 0);

    JSONLoader loader = THREE.JSONLoader();
    loader.load(
        "models/animated/sittingBox.js",
        new JSONLoadHandler() {

          @Override
          public void loaded(Geometry geometry, JsArray<Material> materials) {
            MeshPhongMaterial morphMaterial =
                THREE.MeshPhongMaterial(
                    GWTParamUtils.MeshPhongMaterial()
                        .color(0x000000)
                        .specular(0xff9900)
                        .shininess(50)
                        .morphTargets(true)
                        .side(THREE.DoubleSide)
                        .shading(
                            THREE
                                .FlatShading)); // var morphMaterial = new THREE.MeshPhongMaterial(
                                                // { color: 0x000000, specular: 0xff9900, shininess:
                                                // 50, morphTargets: true, side: THREE.DoubleSide,
                                                // shading: THREE.FlatShading } );

            mesh =
                THREE.Mesh(
                    geometry, morphMaterial); // mesh = new THREE.Mesh( geometry, morphMaterial );

            mixer = THREE.AnimationMixer(mesh); // mixer = new THREE.AnimationMixer( mesh );

            mixer
                .clipAction(geometry.getAnimations().get(0))
                .setDuration(10)
                .play(); // mixer.addAction( new THREE.AnimationAction( geometry.animations[0]
                         // ).warpToDuration( 10 ) );

            double s = 200; // var s = 200;
            mesh.getScale().set(s, s, s); // mesh.scale.set( s, s, s );

            // morph.setDuration(8000);////morph.duration = 8000;
            // morph.setMirroredLoop(true);////morph.mirroredLoop = true;

            mesh.setCastShadow(true); // mesh.castShadow = true;
            mesh.setReceiveShadow(true); // mesh.receiveShadow = true;

            scene.add(mesh);
          }
        });

    double sunIntensity = 0.3;
    double pointIntensity = 1;
    int pointColor = 0xffaa00;

    if (DAY) {

      sunIntensity = 1;
      pointIntensity = 0.5;
      pointColor = 0xffffff;
    }

    ambientLight =
        THREE.AmbientLight(0x3f2806); // ambientLight = new THREE.AmbientLight( 0x3f2806 );
    scene.add(ambientLight);

    pointLight =
        THREE.PointLight(
            0xffaa00,
            pointIntensity,
            5000); // pointLight = new THREE.PointLight( 0xffaa00, pointIntensity, 5000 );
    pointLight.getPosition().set(0, 0, 0); // pointLight.position.set( 0, 0, 0 );
    scene.add(pointLight);

    sunLight =
        THREE.SpotLight(
            0xffffff,
            sunIntensity,
            0,
            Math.PI / 2,
            1); // sunLight = new THREE.SpotLight( 0xffffff, sunIntensity, 0, Math.PI/2, 1 );
    sunLight.getPosition().set(1000, 2000, 1000); // sunLight.position.set( 1000, 2000, 1000 );

    sunLight.setCastShadow(true); // sunLight.castShadow = true;

    sunLight.setShadowBias(-0.0002); // sunLight.shadowBias = -0.0002;

    sunLight.setShadowCameraNear(750); // sunLight.shadowCameraNear = 750;
    sunLight.setShadowCameraFar(4000); // sunLight.shadowCameraFar = 4000;
    sunLight.setShadowCameraFov(30); // sunLight.shadowCameraFov = 30;

    sunLight.setShadowCameraVisible(false); // sunLight.shadowCameraVisible = false;

    scene.add(sunLight);

    // trackball consume keydown event.this is the way to add keydown on root
    // TODO method

    GWTUtils.addKeyDownHandlerToDocument(
        new KeyDownHandler() {
          @Override
          public void onKeyDown(KeyDownEvent event) {

            if (event.getNativeKeyCode() == 78) {
              if (tweenDirection == 1) {

                tweenDay.stop();
                tweenNight.start();

                tweenDirection = -1;

              } else {

                tweenNight.stop();
                tweenDay.start();

                tweenDirection = 1;
              }
            }
          }
        });

    // control

    controls =
        THREEExp.TrackballControls(
            camera,
            renderer
                .getDomElement()); // controls = new THREE.TrackballControls( camera,
                                   // renderer.domElement );
    controls.getTarget().set(0, 120, 0); // controls.target.set( 0, 120, 0 );

    controls.setRotateSpeed(1.0); // controls.rotateSpeed = 1.0;
    controls.setZoomSpeed(1.2); // controls.zoomSpeed = 1.2;
    controls.setPanSpeed(0.8); // controls.panSpeed = 0.8;

    controls.setNoZoom(false); // controls.noZoom = false;
    controls.setNoPan(false); // controls.noPan = false;

    controls.setStaticMoving(true); // controls.staticMoving = true;
    controls.setDynamicDampingFactor(0.15); // controls.dynamicDampingFactor = 0.15;

    controls.setKeys(
        JavaScriptUtils.toArray(new int[] {65, 83, 68})); // controls.keys = [ 65, 83, 68 ];

    // Tween
    tweenDirection = -1;

    parameters = JSParameter.createParameter().set("control", 0);

    tweenDay =
        TWEEN.Tween(parameters).to("control", 1, 1000).easing(TWEEN.Easing_Exponential_Out());
    tweenNight =
        TWEEN.Tween(parameters).to("control", 0, 1000).easing(TWEEN.Easing_Exponential_Out());

    stats = Stats.create();
    stats.setPosition(0, 0);
    container.getElement().appendChild(stats.domElement());

    // add html info
    container.add(
        createAbsoluteHTML(
            "<div style='text:white'><a href='http://threejs.org' target='_blank'>three.js</a>  - test</a>",
            100,
            10));

    // handle resize & gui
    initResizeHandlerAndGUI();
    // setDebugAnimateOneTimeOnly(true);

  }