/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.opengl.examples;


import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.opengl.*;
import org.eclipse.swt.widgets.*;

class LightTab extends OpenGLTab {
	private float[] materialShininess = { 25.0f };
	private float[] lightPosition = { 0.0f, 0.0f, 0.0f, 1.0f };
	private float[][] colorValues = {
		{ 1.0f, 1.0f, 1.0f, 1.0f },	// light diffuse
		{ 1.0f, 1.0f, 1.0f, 1.0f },	// light ambient
		{ 1.0f, 1.0f, 1.0f, 1.0f },	// light specular
		{ 0.5f, 0.5f, 0.5f, 1.0f },	// light main ambient
		{ 0.0f, 0.0f, 1.0f, 1.0f },	// material diffuse
		{ 0.3f, 0.3f, 0.3f, 1.0f },	// material ambient
		{ 1.0f, 1.0f, 1.0f, 1.0f }	// material specular
	};
	private float yPos = 0.0f, xPos = 0.0f, zPos = -20.0f;
	private int quadratic, sphere;
	// sourceType values: 0 = light, 1 = material
	private int sourceType;
	// lightType values: 0 = diffuse, 1 = ambient, 2 = specular, 3 = main ambient 
	private int lightType = 0;

	/**
	 * @see OpenGLTab#createControls(Composite)
	 */
	void createControls(Composite composite) {
		Group movementGroup = new Group(composite, SWT.NONE);
		movementGroup.setText("Translation");
		movementGroup.setLayout(new GridLayout(2, false));

		new Label(movementGroup, SWT.NONE).setText("X:");
		final Slider xMove = new Slider(movementGroup, SWT.NONE);
		xMove.setIncrement(1);
		xMove.setMaximum(22);
		xMove.setMinimum(0);
		xMove.setThumb(2);
		xMove.setPageIncrement(2);
		xMove.setSelection(10);
		xMove.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				xPos = xMove.getSelection() - 10;
			}
		});

		new Label(movementGroup, SWT.NONE).setText("Y:");
		final Slider yMove = new Slider(movementGroup, SWT.NONE);
		yMove.setIncrement(1);
		yMove.setMaximum(22);
		yMove.setMinimum(0);
		yMove.setThumb(2);
		yMove.setPageIncrement(2);
		yMove.setSelection(10);
		yMove.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				yPos = yMove.getSelection() - 10;
			}
		});

		new Label(movementGroup, SWT.NONE).setText("Z:");
		final Slider zMove = new Slider(movementGroup, SWT.NONE);
		zMove.setIncrement(1);
		zMove.setMaximum(22);
		zMove.setMinimum(0);
		zMove.setThumb(2);
		zMove.setPageIncrement(2);
		zMove.setSelection(10);
		zMove.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				zPos = zMove.getSelection() - 30;
			}
		});

		Group positionGroup = new Group(composite, SWT.NONE);
		positionGroup.setText("Light Position");
		positionGroup.setLayout(new GridLayout(2, false));

		new Label(positionGroup, SWT.NONE).setText("X:");
		final Slider lightX = new Slider(positionGroup, SWT.NONE);
		lightX.setIncrement(1);
		lightX.setMaximum(22);
		lightX.setMinimum(0);
		lightX.setThumb(2);
		lightX.setPageIncrement(2);
		lightX.setSelection(10);
		lightX.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				lightPosition[0] = ((float) lightX.getSelection() * 10) - 100;
			}
		});

		new Label(positionGroup, SWT.NONE).setText("Y:");
		final Slider lightY = new Slider(positionGroup, SWT.NONE);
		lightY.setIncrement(1);
		lightY.setMaximum(22);
		lightY.setMinimum(0);
		lightY.setThumb(2);
		lightY.setPageIncrement(2);
		lightY.setSelection(10);
		lightY.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				lightPosition[1] = ((float) lightY.getSelection() * 10) - 100;
			}
		});

		new Label(positionGroup, SWT.NONE).setText("Z:");
		final Slider lightZ = new Slider(positionGroup, SWT.NONE);
		lightZ.setIncrement(1);
		lightZ.setMaximum(22);
		lightZ.setMinimum(0);
		lightZ.setThumb(2);
		lightZ.setPageIncrement(2);
		lightZ.setSelection(10);
		lightZ.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				lightPosition[2] = ((float) lightZ.getSelection() * 10) - 20;
			}
		});

		Group lightColorsGroup = new Group(composite, SWT.NONE);
		lightColorsGroup.setText("Light Colors");
		lightColorsGroup.setLayout(new GridLayout());
		GridData data = new GridData(GridData.FILL_BOTH);
		lightColorsGroup.setLayoutData(data);

		ColorSelectionGroup lightDiffuseButton =
			new ColorSelectionGroup(lightColorsGroup, SWT.NONE);
		lightDiffuseButton.setText("Diffuse");
		lightDiffuseButton.setRGB(
			new RGB(
				(int) (colorValues[0][0] * 255),
				(int) (colorValues[0][1] * 255),
				(int) (colorValues[0][2] * 255)));
		lightDiffuseButton
			.addColorSelectionListener(new IColorSelectionListener() {
			public void handleColorSelection(RGB rgb) {
				colorValues[0][0] = ((float) rgb.red) / 255;
				colorValues[0][1] = ((float) rgb.green) / 255;
				colorValues[0][2] = ((float) rgb.blue) / 255;
				setColorValues();
			}
		});

		ColorSelectionGroup lightAmbientButton =
			new ColorSelectionGroup(lightColorsGroup, SWT.NONE);
		lightAmbientButton.setText("Ambient");
		lightAmbientButton.setRGB(
			new RGB(
				(int) (colorValues[1][0] * 255),
				(int) (colorValues[1][1] * 255),
				(int) (colorValues[1][2] * 255)));
		lightAmbientButton
			.addColorSelectionListener(new IColorSelectionListener() {
			public void handleColorSelection(RGB rgb) {
				colorValues[1][0] = ((float) rgb.red) / 255;
				colorValues[1][1] = ((float) rgb.green) / 255;
				colorValues[1][2] = ((float) rgb.blue) / 255;
				setColorValues();
			}
		});

		ColorSelectionGroup lightSpecularButton =
			new ColorSelectionGroup(lightColorsGroup, SWT.NONE);
		lightSpecularButton.setText("Specular");
		lightSpecularButton.setRGB(
			new RGB(
				(int) (colorValues[2][0] * 255),
				(int) (colorValues[2][1] * 255),
				(int) (colorValues[2][2] * 255)));
		lightSpecularButton
			.addColorSelectionListener(new IColorSelectionListener() {
			public void handleColorSelection(RGB rgb) {
				colorValues[2][0] = ((float) rgb.red) / 255;
				colorValues[2][1] = ((float) rgb.green) / 255;
				colorValues[2][2] = ((float) rgb.blue) / 255;
				setColorValues();
			}
		});

		ColorSelectionGroup lightMainAmbientButton =
			new ColorSelectionGroup(lightColorsGroup, SWT.NONE);
		lightMainAmbientButton.setText("Main Ambient");
		lightMainAmbientButton.setRGB(
			new RGB(
				(int) (colorValues[3][0] * 255),
				(int) (colorValues[3][1] * 255),
				(int) (colorValues[3][2] * 255)));
		lightMainAmbientButton
			.addColorSelectionListener(new IColorSelectionListener() {
			public void handleColorSelection(RGB rgb) {
				colorValues[3][0] = ((float) rgb.red) / 255;
				colorValues[3][1] = ((float) rgb.green) / 255;
				colorValues[3][2] = ((float) rgb.blue) / 255;
				setColorValues();
			}
		});

		Group materialColorsGroup = new Group(composite, SWT.NONE);
		materialColorsGroup.setText("Material Colors");
		materialColorsGroup.setLayout(new GridLayout());
		data = new GridData(GridData.FILL_BOTH);
		materialColorsGroup.setLayoutData(data);

		ColorSelectionGroup materialDiffuseButton =
			new ColorSelectionGroup(materialColorsGroup, SWT.NONE);
		materialDiffuseButton.setText("Diffuse");
		materialDiffuseButton.setRGB(
			new RGB(
				(int) (colorValues[4][0] * 255),
				(int) (colorValues[4][1] * 255),
				(int) (colorValues[4][2] * 255)));
		materialDiffuseButton
			.addColorSelectionListener(new IColorSelectionListener() {
			public void handleColorSelection(RGB rgb) {
				colorValues[4][0] = ((float) rgb.red) / 255;
				colorValues[4][1] = ((float) rgb.green) / 255;
				colorValues[4][2] = ((float) rgb.blue) / 255;
				setColorValues();
			}
		});

		ColorSelectionGroup materialAmbientButton =
			new ColorSelectionGroup(materialColorsGroup, SWT.NONE);
		materialAmbientButton.setText("Ambient");
		materialAmbientButton.setRGB(
			new RGB(
				(int) (colorValues[5][0] * 255),
				(int) (colorValues[5][1] * 255),
				(int) (colorValues[5][2] * 255)));
		materialAmbientButton
			.addColorSelectionListener(new IColorSelectionListener() {
			public void handleColorSelection(RGB rgb) {
				colorValues[5][0] = ((float) rgb.red) / 255;
				colorValues[5][1] = ((float) rgb.green) / 255;
				colorValues[5][2] = ((float) rgb.blue) / 255;
				setColorValues();
			}
		});

		ColorSelectionGroup materialSpecularButton =
			new ColorSelectionGroup(materialColorsGroup, SWT.NONE);
		materialSpecularButton.setText("Specular");
		materialSpecularButton.setRGB(
			new RGB(
				(int) (colorValues[6][0] * 255),
				(int) (colorValues[6][1] * 255),
				(int) (colorValues[6][2] * 255)));
		materialSpecularButton
			.addColorSelectionListener(new IColorSelectionListener() {
			public void handleColorSelection(RGB rgb) {
				colorValues[6][0] = ((float) rgb.red) / 255;
				colorValues[6][1] = ((float) rgb.green) / 255;
				colorValues[6][2] = ((float) rgb.blue) / 255;
				setColorValues();
			}
		});

		new Label(composite, SWT.NONE).setText("Material Shininess:");
		final Slider shineSlider = new Slider(composite, SWT.NONE);
		shineSlider.setIncrement(5);
		shineSlider.setMaximum(102);
		shineSlider.setMinimum(0);
		shineSlider.setThumb(2);
		shineSlider.setPageIncrement(10);
		shineSlider.setSelection(25);
		shineSlider.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				materialShininess[0] = shineSlider.getSelection();
				GL.glMaterialfv(GL.GL_FRONT_AND_BACK,
					GL.GL_SHININESS,
					materialShininess);
			}
		});
	}

	/**
	 * @see OpenGLTab#dispose()
	 */
	void dispose() {
		super.dispose();
		GLU.gluDeleteQuadric(quadratic);
		GL.glDeleteLists(sphere, 1);
	}

	/**
	 * @see OpenGLTab#getTabText()
	 */
	String getTabText() {
		return "Light";
	}

	/**
	 * @see OpenGLTab#init()
	 */
	void init() {
		GL.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
		GL.glClearDepth(1.0);
		setColorValues();
		GL.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SHININESS, materialShininess);
		quadratic = GLU.gluNewQuadric();
		GLU.gluQuadricNormals(quadratic, GLU.GLU_SMOOTH);
		GL.glHint(GL.GL_LINE_SMOOTH_HINT, GL.GL_NICEST);
		GL.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
		GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
		GL.glPointSize(2.0f);
		GL.glEnable(GL.GL_LIGHTING);
		GL.glEnable(GL.GL_LIGHT0);
		GL.glEnable(GL.GL_DEPTH_TEST);
		sphere = GL.glGenLists(1);
		GL.glNewList(sphere, GL.GL_COMPILE);
		GLU.gluSphere(quadratic, 3, 32, 32);
		GL.glEndList();
	}

	/**
	 * @see OpenGLTab#renderScene()
	 */
	void renderScene() {
		GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
		GL.glLoadIdentity();
		GL.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPosition);
		GL.glTranslatef(xPos, yPos, zPos);
		GL.glCallList(sphere);
	}

	/**
	 * Sets the current color values into the rendered display.
	 */
	void setColorValues() {
		GL.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, colorValues[0]);
		GL.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE, colorValues[4]);
		GL.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT, colorValues[5]);
		GL.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, colorValues[1]);
		GL.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, colorValues[2]);
		GL.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR, colorValues[6]);
		GL.glLightModelfv(GL.GL_LIGHT_MODEL_AMBIENT, colorValues[3]);
		GL.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SHININESS, materialShininess);
	}
}
