import {
	PerspectiveCamera,
	Quaternion,
	Vector3
} from 'three';

/**
 * peppers ghost effect based on http://www.instructables.com/id/Reflective-Prism/?ALLSTEPS
 */

class PeppersGhostEffect {

	constructor( renderer ) {

		const scope = this;

		scope.cameraDistance = 15;
		scope.reflectFromAbove = false;

		// Internals
		let _halfWidth, _width, _height;

		const _cameraF = new PerspectiveCamera(); //front
		const _cameraB = new PerspectiveCamera(); //back
		const _cameraL = new PerspectiveCamera(); //left
		const _cameraR = new PerspectiveCamera(); //right

		const _position = new Vector3();
		const _quaternion = new Quaternion();
		const _scale = new Vector3();

		// Initialization
		renderer.autoClear = false;

		this.setSize = function ( width, height ) {

			_halfWidth = width / 2;
			if ( width < height ) {

				_width = width / 3;
				_height = width / 3;

			} else {

				_width = height / 3;
				_height = height / 3;

			}

			renderer.setSize( width, height );

		};

		this.render = function ( scene, camera ) {

			if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();

			if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();

			camera.matrixWorld.decompose( _position, _quaternion, _scale );

			// front
			_cameraF.position.copy( _position );
			_cameraF.quaternion.copy( _quaternion );
			_cameraF.translateZ( scope.cameraDistance );
			_cameraF.lookAt( scene.position );

			// back
			_cameraB.position.copy( _position );
			_cameraB.quaternion.copy( _quaternion );
			_cameraB.translateZ( - ( scope.cameraDistance ) );
			_cameraB.lookAt( scene.position );
			_cameraB.rotation.z += 180 * ( Math.PI / 180 );

			// left
			_cameraL.position.copy( _position );
			_cameraL.quaternion.copy( _quaternion );
			_cameraL.translateX( - ( scope.cameraDistance ) );
			_cameraL.lookAt( scene.position );
			_cameraL.rotation.x += 90 * ( Math.PI / 180 );

			// right
			_cameraR.position.copy( _position );
			_cameraR.quaternion.copy( _quaternion );
			_cameraR.translateX( scope.cameraDistance );
			_cameraR.lookAt( scene.position );
			_cameraR.rotation.x += 90 * ( Math.PI / 180 );


			renderer.clear();
			renderer.setScissorTest( true );

			renderer.setScissor( _halfWidth - ( _width / 2 ), ( _height * 2 ), _width, _height );
			renderer.setViewport( _halfWidth - ( _width / 2 ), ( _height * 2 ), _width, _height );

			if ( scope.reflectFromAbove ) {

				renderer.render( scene, _cameraB );

			} else {

				renderer.render( scene, _cameraF );

			}

			renderer.setScissor( _halfWidth - ( _width / 2 ), 0, _width, _height );
			renderer.setViewport( _halfWidth - ( _width / 2 ), 0, _width, _height );

			if ( scope.reflectFromAbove ) {

				renderer.render( scene, _cameraF );

			} else {

				renderer.render( scene, _cameraB );

			}

			renderer.setScissor( _halfWidth - ( _width / 2 ) - _width, _height, _width, _height );
			renderer.setViewport( _halfWidth - ( _width / 2 ) - _width, _height, _width, _height );

			if ( scope.reflectFromAbove ) {

				renderer.render( scene, _cameraR );

			} else {

				renderer.render( scene, _cameraL );

			}

			renderer.setScissor( _halfWidth + ( _width / 2 ), _height, _width, _height );
			renderer.setViewport( _halfWidth + ( _width / 2 ), _height, _width, _height );

			if ( scope.reflectFromAbove ) {

				renderer.render( scene, _cameraL );

			} else {

				renderer.render( scene, _cameraR );

			}

			renderer.setScissorTest( false );

		};

	}

}

export { PeppersGhostEffect };
