package j3deditor.bin.editor.tools;

import j3deditor.bin.hierarchy.J3DeScene;
import j3deditor.bin.hierarchy.J3DeTexture;

import j3deditor.bin.hierarchy.util.HierarchyEvent;
import j3deditor.bin.hierarchy.util.HierarchyEventListener;

import j3deditor.bin.util.Utilities;

import java.awt.BorderLayout;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;

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

import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;


/**
 * User interface for manipulating  the attributes of
 * active <code>J3DeTexture</code> node.
 * 
 * @author Risto Seene
 */
public class TexturePanel extends JPanel{

	private J3DeTexture texture;

	private HierarchyEventListener l;

	private JComboBox aniMode;

	private JTextField aniDeg;

	private JTextField bLevel;
	
	private JTextField aColor;

	private JButton bColor;

	private JComboBox bModeS;

	private JComboBox bModeT;

	private JTextField[] f4fW;

	private JTextField[] lOffs;

	private JComboBox maFilter;

	private JComboBox miFilter;

	private JTextField mLevel;

	private JTextField minLod;

	private JTextField maxLod;


	private String invalid;


	/**
	 * Creates an instance of <code>MaterialPanel</code>
	 * which manipulates the specified <code>J3DeTexture</code> node.
	 * 
	 * @param texture
	 * 	texture node this panel manipulates
	 * @param listener
	 * 	hierarchy event listener
	 */
	public TexturePanel(J3DeTexture texture, HierarchyEventListener listener){
		this.texture = texture;
		this.l = listener;

		setLayout(new GridLayout(4, 4, 2, 2));
		setOpaque(false);
		initContent();
	}

	/**
	 * Initializes the content of this panel.
	 */
	private void initContent(){
		invalid = Utilities.translator.translate(this.getClass(), "invalid");
		String sInfo = texture.getSize() + ", " + Utilities.translator.translate(this.getClass(), "format") + " " + texture.getFormats()[texture.getFormat()] + ", " + texture.numMipMapLevels() + " " + Utilities.translator.translate(this.getClass(), "mmLevels");
		this.add(new JLabel(sInfo));
		this.add(new JLabel());

		aniMode = new JComboBox();
		String[] aniModes = J3DeTexture.getAnisotropicFilterModes();
		for(int i = 0; i < aniModes.length; i++){
			aniMode.addItem(aniModes[i]);
		}
		aniMode.setSelectedIndex(texture.getAnisotropicFilterMode());
		aniMode.addActionListener(new ActionListener(){

				public void actionPerformed(ActionEvent e){
					try{
						detachSceneGraph();
						texture.setAnisotropicFilterMode(aniMode.getSelectedIndex());
					} catch(Throwable t){
						Utilities.out.throwWarning(t);
					}
					reattachSceneGraph();
				}
			});
		aniMode.setToolTipText(Utilities.translator.translate(this.getClass(), "aniMode"));
		this.add(aniMode);

		aniDeg = new JTextField(texture.getAnisotropicFilterDegree() + "");
		aniDeg.addActionListener(new ActionListener(){

				public void actionPerformed(ActionEvent e){
					try{
						detachSceneGraph();
						texture.setAnisotropicFilterDegree(Float.parseFloat(aniDeg.getText()));
					} catch(Throwable t){
						Utilities.out.throwWarning(invalid);
					}
					aniDeg.setText(texture.getAnisotropicFilterDegree() + "");
					reattachSceneGraph();
				}
			});
		aniDeg.setToolTipText(Utilities.translator.translate(this.getClass(), "aniDeg"));
		this.add(aniDeg);
		
	          float[] weights = texture.getFilter4Func();
	          f4fW = new JTextField[weights.length];
	          JPanel f4Panel = new JPanel(new GridLayout(1, weights.length));
	          for(int i = 0; i < weights.length; i++){
	                    JTextField w = new JTextField(weights[i] + "");
	                    f4fW[i] = w;
	                    w.addActionListener(new ActionListener(){

	                                        public void actionPerformed(ActionEvent e){
	                                                  try{
	                                                            float[] ws = new float[f4fW.length];
	                                                            for(int i = 0; i < ws.length; i++){
	                                                                      ws[i] = Float.parseFloat(f4fW[i].getText());
	                                                            }
	                                                            texture.setFilter4Func(ws);
	                                                  } catch(Throwable t){
							Utilities.out.throwWarning(invalid);
	                                                  }
	                                                  float[] ws = texture.getFilter4Func();
	                                                  for(int i = 0; i < ws.length; i++){
	                                                            f4fW[i].setText(ws[i] + "");
	                                                  }
	                                        }
	                              });
	                    w.setToolTipText(Utilities.translator.translate(TexturePanel.class, "f4fW"));
	                    f4Panel.add(w);
	          }
	          f4Panel.setOpaque(false);
	          this.add(f4Panel);
		
		this.add(new JLabel());

		bLevel = new JTextField(texture.getBaseLevel() + "");
		bLevel.addActionListener(new ActionListener(){

				public void actionPerformed(ActionEvent e){
					try{
						texture.setBaseLevel(Integer.parseInt(bLevel.getText()));
					} catch(Throwable t){
						Utilities.out.throwWarning(invalid);
					}
					bLevel.setText(texture.getBaseLevel() + "");
				}
			});
		bLevel.setToolTipText(Utilities.translator.translate(this.getClass(), "bLevel"));
		this.add(bLevel);

		mLevel = new JTextField(texture.getMaximumLevel() + "");
		mLevel.addActionListener(new ActionListener(){

				public void actionPerformed(ActionEvent e){
					try{
						texture.setMaximumLevel(Integer.parseInt(mLevel.getText()));
					} catch(Throwable t){
						Utilities.out.throwWarning(invalid);
					}
					mLevel.setText(texture.getMaximumLevel() + "");
				}
			});
		mLevel.setToolTipText(Utilities.translator.translate(this.getClass(), "mLevel"));
		this.add(mLevel);

		JPanel cPanel = new JPanel(new BorderLayout());
		aColor = new JTextField((((double)texture.getBoundaryColor().getAlpha())/255) + "");
		aColor.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				try{
					int alpha = (int)(255 * Float.parseFloat(aColor.getText()));
					if(alpha < 0){
						alpha = 0;
					}
					else if(alpha > 255){
						alpha = 255;
					}
					Color color = texture.getBoundaryColor();
					Color newColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha);
				          detachSceneGraph();
					texture.setBoundaryColor(newColor);
				} catch(Throwable t){
						Utilities.out.throwWarning(invalid);
				}
				aColor.setText((((double)texture.getBoundaryColor().getAlpha())/255) + "");
			          reattachSceneGraph();
			}
		});
		aColor.setToolTipText(Utilities.translator.translate(this.getClass(), "aColor"));
		aColor.setPreferredSize(new Dimension(30, 30));
		cPanel.add(aColor, BorderLayout.WEST);
	          bColor = new JButton(Utilities.translator.translate(this.getClass(), "bColor"));
	          Color color = texture.getBoundaryColor();
	          bColor.setForeground(new Color(color.getRed(), color.getGreen(), color.getBlue()));
	          bColor.addActionListener(new ActionListener(){

	                              public void actionPerformed(ActionEvent e){
	                                        try{
	                                                  Color color = texture.getBoundaryColor();
	                                                  String title = Utilities.translator.translate(TexturePanel.class, "bColor");
						Color newColor1 = new Color(color.getRed(), color.getGreen(), color.getBlue());
	                                                  newColor1 = new JColorChooser().showDialog(new JFrame(), title, newColor1);
						if(newColor1 == null){
							return;
						}
						Color newColor2 = new Color(newColor1.getRed(), newColor1.getGreen(), newColor1.getBlue(), color.getAlpha());
	                                                  detachSceneGraph();
						texture.setBoundaryColor(newColor2);
	                                        } catch(Throwable t){
						Utilities.out.throwWarning(t);
	                                        }
					Color color = texture.getBoundaryColor();
	                                        bColor.setForeground(new Color(color.getRed(), color.getGreen(), color.getBlue()));
	                                        reattachSceneGraph();
	                              }
	                    });
	          bColor.setToolTipText(Utilities.translator.translate(this.getClass(), "bColor"));
		cPanel.add(bColor, BorderLayout.CENTER);
		cPanel.setOpaque(false);
	          this.add(cPanel);

		JPanel loPanel = new JPanel(new GridLayout(1, 3));
		float[] offs = texture.getLodOffset();
		lOffs = new JTextField[3];
		for(int i = 0; i < 3; i++){
			JTextField lo = new JTextField(offs[i] + "");
			lOffs[i] = lo;
			lo.addActionListener(new ActionListener(){

					public void actionPerformed(ActionEvent e){
						try{
							texture.setLodOffset(Float.parseFloat(lOffs[0].getText()), Float.parseFloat(lOffs[1].getText()), Float.parseFloat(lOffs[2].getText()));
						} catch(Throwable t){
							Utilities.out.throwWarning(invalid);
						}
						float[] offs = texture.getLodOffset();
						for(int i = 0; i < 3; i++){
							lOffs[i].setText(offs[i] + "");
						}
					}
				});
			lo.setToolTipText(Utilities.translator.translate(TexturePanel.class, "lOffs"));
			loPanel.add(lo);
		}
		loPanel.setOpaque(false);
		this.add(loPanel);

		minLod = new JTextField(texture.getMinimumLOD() + "");
		minLod.addActionListener(new ActionListener(){

				public void actionPerformed(ActionEvent e){
					try{
						texture.setMinimumLOD(Float.parseFloat(minLod.getText()));
					} catch(Throwable t){
						Utilities.out.throwWarning(invalid);
					}
					minLod.setText(texture.getMinimumLOD() + "");
				}
			});
		minLod.setToolTipText(Utilities.translator.translate(this.getClass(), "minLod"));
		this.add(minLod);

		maxLod = new JTextField(texture.getMaximumLOD() + "");
		maxLod.addActionListener(new ActionListener(){

				public void actionPerformed(ActionEvent e){
					try{
						texture.setMaximumLOD(Float.parseFloat(maxLod.getText()));
					} catch(Throwable t){
						Utilities.out.throwWarning(invalid);
					}
					maxLod.setText(texture.getMaximumLOD() + "");
				}
			});
		maxLod.setToolTipText(Utilities.translator.translate(this.getClass(), "maxLod"));
		this.add(maxLod);
		
	          bModeS = new JComboBox();
	          String[] bModes = J3DeTexture.getBoundaryModes();
	          for(int i = 0; i < bModes.length; i++){
	                    bModeS.addItem(bModes[i]);
	          }
	          bModeS.setSelectedIndex(texture.getBoundaryModeS());
	          bModeS.addActionListener(new ActionListener(){

	                              public void actionPerformed(ActionEvent e){
	                                        try{
	                                                  detachSceneGraph();
	                                                  texture.setBoundaryModeS(bModeS.getSelectedIndex());
	                                        } catch(Throwable t){
						Utilities.out.throwWarning(t);
	                                        }
	                                        reattachSceneGraph();
	                              }
	                    });
	          bModeS.setToolTipText(Utilities.translator.translate(this.getClass(), "bModeS"));
	          this.add(bModeS);

	          bModeT = new JComboBox();
	          for(int i = 0; i < bModes.length; i++){
	                    bModeT.addItem(bModes[i]);
	          }
	          bModeT.setSelectedIndex(texture.getBoundaryModeT());
	          bModeT.addActionListener(new ActionListener(){

	                              public void actionPerformed(ActionEvent e){
	                                        try{
	                                                  detachSceneGraph();
	                                                  texture.setBoundaryModeT(bModeT.getSelectedIndex());
	                                        } catch(Throwable t){
						Utilities.out.throwWarning(t);
	                                        }
	                                        reattachSceneGraph();
	                              }
	                    });
	          bModeT.setToolTipText(Utilities.translator.translate(this.getClass(), "bModeT"));
	          this.add(bModeT);
		
	          miFilter = new JComboBox();
	          String[] miFs = J3DeTexture.getMinFilters();
	          for(int i = 0; i < miFs.length; i++){
	                    miFilter.addItem(miFs[i]);
	          }
	          miFilter.setSelectedIndex(texture.getMinFilter());
	          miFilter.addActionListener(new ActionListener(){

	                              public void actionPerformed(ActionEvent e){
	                                        try{
	                                                  detachSceneGraph();
	                                                  texture.setMinFilter(miFilter.getSelectedIndex());
	                                        } catch(Throwable t){
						Utilities.out.throwWarning(t);
	                                        }
	                                        reattachSceneGraph();
	                              }
	                    });
	          miFilter.setToolTipText(Utilities.translator.translate(this.getClass(), "miFilter"));
	          this.add(miFilter);

	          maFilter = new JComboBox();
	          String[] maFs = J3DeTexture.getMagFilters();
	          for(int i = 0; i < maFs.length; i++){
	                    maFilter.addItem(maFs[i]);
	          }
	          maFilter.setSelectedIndex(texture.getMagFilter());
	          maFilter.addActionListener(new ActionListener(){

	                              public void actionPerformed(ActionEvent e){
	                                        try{
	                                                  detachSceneGraph();
	                                                  texture.setMagFilter(maFilter.getSelectedIndex());
	                                        } catch(Throwable t){
						Utilities.out.throwWarning(t);
	                                        }
	                                        reattachSceneGraph();
	                              }
	                    });
	          maFilter.setToolTipText(Utilities.translator.translate(this.getClass(), "maFilter"));
	          this.add(maFilter);
	}


	/**
	 * Detaches scene graph.
	 */
	private void detachSceneGraph(){
		J3DeScene scene = ((J3DeScene)this.texture.getParent(J3DeScene.class));
		if(scene != null){
			scene.detach();
		}
	}

	/**
	 * Reattaches scene graph.
	 */
	private void reattachSceneGraph(){
		if(this.l != null){
			l.hierarchyEventOccured(new HierarchyEvent(this, HierarchyEvent.OBJECT_ALTERATION));
		}
	}

}
