/// Image Scene: Step 1

EnableMenu( false );
EnableStdCtrl( false );

// Things that should only be done once at the start of the script
if ( ExecMode & EM_CHANGE )
{
	// Define Function to create an image scene
	ImageScene_Create =
	{
		// Return values:
		// 1. The image scene
		scImage -> _P(1);
		
		// 2. Texture Reference to quickly change image content later
		texImg -> _P(2);

		// Shader reference
		shImage -> _P(3);
		
		// Luminance shader reference
		shImageLum -> _P(4);
		
		// Input Values:
		// The scene name
		sName = _P(5);

		// The size of the image that will be drawn.
		// Only the aspect ratio is important not the absolute size.
		iWidth = _P(6);
		iHeight = _P(7);
		
		// Dummy image
		imgA = Image(iWidth,iHeight, Blue);
		
		// Get the image size
		lImgSize = [iWidth, iHeight];
		
		///////////////////////////////////////////////////////////
		/// Create Shader
		///
		/// The image will be updated from the external program
		/// by writing directly from CUDA memory into the texture created further below.
		/// However, CUDA can only copy unnormalized textures, which means
		/// we need a special shader to actually display the texture.
		/// This texture is defined below.
		
		// The vertex shader
		sVSCode = "
			varying out vec2 vTexPos;
			
			void main()
			{
				vec2 texpos = gl_MultiTexCoord0.st;
				vTexPos = vec4( texpos, 0.0, 0.0 );
				gl_Position = ftransform();
			}
		";
	
	
		sFSCode = "
			#version 130
			//#pragma optimize(on)
			
			in vec2 vTexPos;
			out vec4 gl_FragColor;
			
			// The image texture
			uniform usampler2D texImg;
			
			void main()
			{			
				vec3 vCol = vec3(textureLod(texImg, vTexPos, 0).xyz) / 255.0;
				gl_FragColor = vec4(vCol, 1.0);
			}
		";

		sFSCode_Lum = "
			#version 130
			//#pragma optimize(on)
			
			in vec2 vTexPos;
			out vec4 gl_FragColor;
			
			// The image texture
			uniform usampler2D texImg;
			
			void main()
			{			
				float fCol = float(textureLod(texImg, vTexPos, 0).x) / 255.0;
				gl_FragColor = vec4(fCol, fCol, fCol, 1.0);
			}
		";

		shDefault = Shader( "Default" );
		shImage = Shader( "Image" );
		shImageLum = Shader( "ImageLum" );
		ShaderBuild( shImage, [sVSCode], [sFSCode] );
		ShaderBuild( shImageLum, [sVSCode], [sFSCode_Lum] );
		EnableShader( shImageLum, false );
		
		///////////////////////////////////////////////////////////
		// Create Image Texture
		
		// Create a texture element
		texImg = Texture( sName + "_image" );
		
		// Set the image as texture
		// MipMaps are switched off. Usually, when textures are used 
		// to make objects in a 3D-World look good, MipMaps are generated
		// which a scaled down versions of the original texture.
		// These smaller versions of the texture are used, when an 
		// object is further away and thus so small that the full
		// texture details cannot be seen in any case.
		SetTextureImage( texImg, imgA, false /* no MipMaps */);
		
		// Switch texture interpolation off, so that single pixels
		// are seen when zooming in.
		EnableTextureInterpolate( texImg, false );
		///////////////////////////////////////////////////////////

		
		///////////////////////////////////////////////////////////
		// Create Scene
		scImage = Scene( sName );
		
		lPixCnt = Size(texImg)("size");
		lHalfPixCnt = floor(lPixCnt / 2);
		dAspect = lPixCnt(2) / lPixCnt(1);

		//lVirtPixCnt = floor(lPixCnt / 2);
		
		lVisSize = GetVisWinSize();
		lIdx = argmin( lVisSize );
		dFactor = lVisSize(lIdx)(1) / lPixCnt(lIdx)(1);
				
		//scDraw = Scene( sName + "_Draw" );
	
		SetSceneOverlay( scImage, 0, lPixCnt(1), 0, lPixCnt(2), -5, 5, true );
		//SetSceneOverlay( scRender, 0, 2, 0, 2, -1, 1, false );
		
		//SetSceneViewport( scImage, 0, 0, lVirtPixCnt(1), lVirtPixCnt(2), true );

		EnableSceneResetFrame( scImage, true );	
		EnableScenePick( scImage, true );
		EnableSceneDrag( scImage, 1, false, true );
		EnableSceneDrag( scImage, 2, false, true );
		EnableSceneAutoTranslate( scImage, true );
		EnableSceneAutoScale( scImage, true );
		SetSceneAutoDragControl( scImage, 
					[ [ 2, false ] /* scale */, 
					  [ 2, true ] /* Rotate 1 */, 
					  [ 1, false ] /* Translate */, 
					  [ 1, true ] /* Rotate 2 */ ] );
		
		EnableSceneDragInScreenPlane( scImage, 1, false, true );
		SetSceneScaleType( scImage, "mouse" );
		SetSceneScaleFunc( scImage, "exp" );
		SetSceneDragFactor( scImage, 2, false, [ 1, 1, 1 ] );
		SetSceneDragBasis( scImage, 2, false, [ VecE3(0,0,0), VecE3(0,0,0), VecE3(1,1,0) ] );
	
		SetSceneDragData( scImage, 1, false, [ 0, 0, 0 ] );
		SetSceneDragData( scImage, 2, false, [ 0, 0, 0 ] );
		
	
		///////////////////////////////////////////////////////////////////////////////
		// Define what is to be drawn inside the scene
		DrawToScene( scImage );
			// Make the image texture active
			:texImg;
			:shImage;
			:shImageLum;
			
			// Draw a plane which has the size of the image
			// onto which the image is mapped.
			// The color of this plane is multiplied with the 
			// texture color. So we set it to 'white' to see
			// the original image.
			:White;
			DrawPlane(  VecE3(lPixCnt/2), /* center */
						VecE3( lPixCnt(1), 0 ), /* x-extent */
						VecE3( 0, -lPixCnt(2) ) /* y-extent, flip y-axis */ );
			
			// Switch texture mapping off
			SetTexture();
			:shDefault;
			
		DrawToScene();
		///////////////////////////////////////////////////////////
		
	} // end of function
	
	///////////////////////////////////////////////////////////
	// Create a light element to switch lighting off
	// Light 1 is the standard light, which is by default switched on.
	liA = Light( "A", 1 /* Light 1 */); 
	// Disable the light. Note that the light still has to be 
	// applied with the ':' operator to take effect.
	EnableLight( liA, false );
	
	// Create an ambient light element, to set ambient light to maximum
	aliA = AmbientLight( "A" );
	// Set ambient light to white.
	SetAmbientLight( aliA, White );
	
	///////////////////////////////////////////////////////////

	texImage = 0;
	iWidth = 1;
	iHeight = 1;
	
	bImgOK = false;

	// Load an example image
	//imgA = ReadImg( "Logo_Raytrix_512x320.png" );
	
	// Create the image scene
	//ImageScene_Create( scImage, shImage, "Test", imgA );
	//EnableShader( shImage, bSelectColChan );
}

if ( ToolName == "Image_Create" )
{
	// Create the image scene. This does not set the actual image.
	// The image is set by directly copying from CUDA memory
	// into the texture returned in texImage.
	ImageScene_Create( scImage, texImage, shImage, shImageLum, "Image", iWidth, iHeight );
	bImgOK = true;
}
// If the image texture is of luminance type, the appropriate
// shader has to be enabled. Otherwise, the image is displayed
// incorrectly.
else if ( ToolName == "Image_Lum_Enable" )
{
	EnableShader( shImage, false );
	EnableShader( shImageLum, true );
}
else if ( ToolName == "Image_Lum_Disable" )
{
	EnableShader( shImage, true );
	EnableShader( shImageLum, false );
}

// Display a standard text if no image is initialized
if ( !!bImgOK )
{	
	_BGColor = Black;
	SetImagePos( 0, 0, 0 );
	SetImageAlign( 0.5, 0.5 );
	:DWhite;
	:"CLUViz Control";
	break;
}


// Apply lights.
// Switch localized light off
:liA;
// Set Ambient light to maximum
:aliA;

// Draw the image scene
:scImage;
