package j3deditor.bin.editor.tools;

import j3deditor.bin.components.PopupDialog;

import j3deditor.bin.hierarchy.J3DeGeometry;
import j3deditor.bin.hierarchy.J3DeGeometryArray;
import j3deditor.bin.hierarchy.J3DeShape3D;

import j3deditor.bin.util.Utilities;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.media.j3d.GeometryArray;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;


/**
 * Dialog for replacing or adding a new geometry to a Shape3D node.
 * 
 * @author Risto Seene
 */
public class NewGeometryDialog extends PopupDialog{

	private J3DeShape3D object;

	private int geometryCount;

	private JComboBox gIndex;

	private JButton change;

	private JComboBox geometry;

	private JCheckBox byReference;

	private JCheckBox interleaved;

	private JTextField faceCount;

	private JLabel vertCount;

	private JCheckBox texture;

	private JComboBox texType;

	private JCheckBox color;

	private JComboBox clrType;

	private JCheckBox normals;


	/**
	 * Creates an instance of <code>NewGeometryDialog</code>.
	 * 
	 * @param object
	 * 	Shape3D node which geometry will be replaced or which will
	 *        be added a new geometry
	 */
	public NewGeometryDialog(J3DeShape3D object){
		this.initDialog(Utilities.image.getImage("icons/geometry.png"), Utilities.translator.translate(this.getClass(), "title"), 400, 380);
		this.object = object;

		this.initContent();
		this.setVisible(true);
	}

	/**
	 * Initializes the content of this dialog.
	 */
	private void initContent(){
		JPanel panel = new JPanel();
		panel.setLayout(null);
		this.add(panel);

		this.gIndex = new JComboBox();
		this.geometryCount = this.object.getGeometries().length;
		for(int i = 0; i < geometryCount; i++){
			gIndex.addItem(Utilities.translator.translate(this.getClass(), "setGeom") + " " + (i + 1));
		}
		gIndex.addItem(Utilities.translator.translate(this.getClass(), "newGeom"));
		gIndex.addActionListener(new ActionListener(){

				public void actionPerformed(ActionEvent e){
					if(gIndex.getSelectedIndex() == geometryCount){
						change.setEnabled(false);
					}
					else {
						change.setEnabled(true);
					}
				}
			});
		gIndex.setBounds(20, 20, 350, (int)(gIndex.getPreferredSize().getHeight()));
		panel.add(gIndex);

		this.change = new JButton(Utilities.translator.translate(this.getClass(), "change"));
		change.addActionListener(new ActionListener(){

				public void actionPerformed(ActionEvent e){
					try{
						dispose();
						new ChangeGeometryDialog(object, gIndex.getSelectedIndex());
					} catch(Throwable t){
						Utilities.out.throwError(t);
					}
				}
			});
		change.setBounds(20, 50, 350, (int)(change.getPreferredSize().getHeight()));
		panel.add(change);

		this.geometry = new JComboBox();
		geometry.addItem(Utilities.translator.translate(this.getClass(), "pointG"));
		geometry.addItem(Utilities.translator.translate(this.getClass(), "lineG"));
		geometry.addItem(Utilities.translator.translate(this.getClass(), "triG"));
		geometry.addItem(Utilities.translator.translate(this.getClass(), "quadG"));
		geometry.setSelectedIndex(2);
		geometry.setBounds(140, 110, 230, (int)(geometry.getPreferredSize().getHeight()));
		JLabel type = new JLabel(Utilities.translator.translate(this.getClass(), "gType"), JLabel.RIGHT);
		type.setBounds(20, 110, 115, (int)(geometry.getPreferredSize().getHeight()));
		panel.add(type);
		panel.add(geometry);

		this.byReference = new JCheckBox("BY REFERENCE", false);
		byReference.setBounds(60, 140, (int)(byReference.getPreferredSize().getWidth()), (int)(byReference.getPreferredSize().getHeight()));
		byReference.addActionListener(new ActionListener(){

				public void actionPerformed(ActionEvent e){
					updateInterleaved();
				}
			});
		panel.add(byReference);

		this.interleaved = new JCheckBox("INTERLEAVED", false);
		interleaved.setEnabled(false);
		interleaved.setBounds(200, 140, (int)(interleaved.getPreferredSize().getWidth()), (int)(interleaved.getPreferredSize().getHeight()));
		panel.add(interleaved);

		this.faceCount = new JTextField("10", 10);
		faceCount.setBounds(160, 180, 80, (int)(faceCount.getPreferredSize().getHeight()));
		JLabel pCount = new JLabel(Utilities.translator.translate(this.getClass(), "polygons"), JLabel.RIGHT);
		pCount.setBounds(20, 180, 135, (int)(faceCount.getPreferredSize().getHeight()));
		panel.add(pCount);
		panel.add(faceCount);
		this.vertCount = new JLabel();
		vertCount.setBounds(245, 180, 125, (int)(faceCount.getPreferredSize().getHeight()));
		recalculateVertCount();
		panel.add(vertCount);

		String tex = Utilities.translator.translate(this.getClass(), "texture");
		texture = new JCheckBox(tex, false);
		texture.setBounds(20, 210, 180, (int)(texture.getPreferredSize().getHeight()));
		texture.addActionListener(new ActionListener(){

				public void actionPerformed(ActionEvent e){
					updateTextype();
				}
			});
		panel.add(texture);

		texType = new JComboBox();
		texType.addItem("2D " + tex);
		texType.addItem("3D " + tex);
		texType.addItem("4D " + tex);
		texType.setSelectedIndex(0);
		texType.setEnabled(false);
		texType.setBounds(200, 210, 170, (int)(texture.getPreferredSize().getHeight()));
		panel.add(texType);

		String clr = Utilities.translator.translate(this.getClass(), "color");
		color = new JCheckBox(clr, false);
		color.setBounds(20, 240, 180, (int)(color.getPreferredSize().getHeight()));
		color.addActionListener(new ActionListener(){

				public void actionPerformed(ActionEvent e){
					updateClrtype();
				}
			});
		panel.add(color);

		clrType = new JComboBox();
		clrType.addItem(clr + " 3");
		clrType.addItem(clr + " 4");
		clrType.setSelectedIndex(0);
		clrType.setEnabled(false);
		clrType.setBounds(200, 240, 170, (int)(color.getPreferredSize().getHeight()));
		panel.add(clrType);

		normals = new JCheckBox(Utilities.translator.translate(this.getClass(), "normals"), false);
		normals.setBounds(20, 270, 180, (int)(normals.getPreferredSize().getHeight()));
		panel.add(normals);

		JButton ok = new JButton(Utilities.translator.translate(this.getClass(), "ok"));
		ok.setBounds(100, 320, 100, (int)(ok.getPreferredSize().getHeight()));
		ok.addActionListener(new ActionListener(){

				public void actionPerformed(ActionEvent e){
					setGeometry();
				}
			});
		panel.add(ok);

		JButton cancel = new JButton(Utilities.translator.translate(this.getClass(), "cancel"));
		cancel.setBounds(205, 320, 100, (int)(cancel.getPreferredSize().getHeight()));
		cancel.addActionListener(new ActionListener(){

				public void actionPerformed(ActionEvent e){
					dispose();
				}
			});
		panel.add(cancel);


		geometry.addActionListener(new ActionListener(){

				public void actionPerformed(ActionEvent e){
					recalculateVertCount();
				}
			});
		faceCount.addCaretListener(new CaretListener(){

				public void caretUpdate(CaretEvent e){
					recalculateVertCount();
				}
			});
	}

	/**
	 * Updates UI.
	 */
	private void updateInterleaved(){
		if(this.byReference.isSelected()){
			this.interleaved.setEnabled(true);
		}
		else {
			this.interleaved.setSelected(false);
			this.interleaved.setEnabled(false);
		}
	}

	/**
	 * Updates UI.
	 */
	private void recalculateVertCount(){
		int polyCount = 0;
		int faceSize = this.geometry.getSelectedIndex() + 1;

		try{
			polyCount = Integer.parseInt(this.faceCount.getText());
		} catch(Throwable t){
		}
		int vertCount = polyCount * faceSize;
		if(vertCount < 0){
			vertCount = 0;
		}
		this.vertCount.setText("(" + vertCount + " " + Utilities.translator.translate(this.getClass(), "verts") + ")");
	}

	/**
	 * Updates UI.
	 */
	private void updateTextype(){
		if(this.texture.isSelected()){
			this.texType.setEnabled(true);
		}
		else {
			this.texType.setEnabled(false);
		}
	}

	/**
	 * Updates UI.
	 */
	private void updateClrtype(){
		if(this.color.isSelected()){
			this.clrType.setEnabled(true);
		}
		else {
			this.clrType.setEnabled(false);
		}
	}

	/**
	 * Sets new geometry.
	 */
	private void setGeometry(){
		try{
			int type = geometry.getSelectedIndex() + 1;

			int vertCount = 0;
			try{
				vertCount = Integer.parseInt(this.faceCount.getText()) * type;
				if(vertCount < 0){
					vertCount = 0;
				}
			} catch(Throwable t){
			}

			int vertFormat = GeometryArray.COORDINATES;
			if(this.byReference.isSelected()){
				vertFormat = vertFormat | GeometryArray.BY_REFERENCE;
				if(this.interleaved.isSelected()){
					vertFormat = vertFormat | GeometryArray.INTERLEAVED;
				}
			}
			if(this.texture.isSelected()){
				if(texType.getSelectedIndex() == 0){
					vertFormat = vertFormat | GeometryArray.TEXTURE_COORDINATE_2;
				}
				else if(texType.getSelectedIndex() == 1){
					vertFormat = vertFormat | GeometryArray.TEXTURE_COORDINATE_3;
				}
				else if(texType.getSelectedIndex() == 2){
					vertFormat = vertFormat | GeometryArray.TEXTURE_COORDINATE_4;
				}
			}
			if(this.color.isSelected()){
				if(clrType.getSelectedIndex() == 0){
					vertFormat = vertFormat | GeometryArray.COLOR_3;
				}
				else if(clrType.getSelectedIndex() == 1){
					vertFormat = vertFormat | GeometryArray.COLOR_4;
				}
			}
			if(this.normals.isSelected()){
				vertFormat = vertFormat | GeometryArray.NORMALS;
			}

			J3DeGeometry g = J3DeGeometryArray.createNewGeometryArray(type, vertCount, vertFormat);

			if(this.gIndex.getSelectedIndex() == this.geometryCount){
				this.object.addGeometry(g);
			}
			else {
				this.object.setGeometry(g, this.gIndex.getSelectedIndex());
			}

			this.dispose();
		} catch(Throwable t){
			Utilities.out.throwError(t);
		}
	}

}
