/*
* Copyright (c) 1997 - 2016
* Actelion Pharmaceuticals Ltd.
* Gewerbestrasse 16
* CH-4123 Allschwil, Switzerland
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
*    list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
*    this list of conditions and the following disclaimer in the documentation
*    and/or other materials provided with the distribution.
* 3. Neither the name of the the copyright holder nor the
*    names of its contributors may be used to endorse or promote products
*    derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

package com.actelion.research.gui.editor;

import com.actelion.research.chem.ExtendedMolecule;
import com.actelion.research.chem.Molecule;
import com.actelion.research.gui.generic.GenericComboBox;
import com.actelion.research.gui.generic.GenericDialog;
import com.actelion.research.gui.generic.GenericDialogHelper;
import com.actelion.research.gui.generic.GenericTextField;

import javax.swing.*;

public class AtomLabelDialogBuilder implements DialogEventConsumer {
    public static final long serialVersionUID = 0x20080213;

    private static final String[] RADICAL_STATES = { "None", "One electron (duplet)", "Two electrons (triplet)", "Two electrons (singulet)" };

	private GenericDialog mDialog;
    private ExtendedMolecule mMol;
    private int mAtom;
    private GenericTextField mTextFieldLabel,mTextFieldMass,mTextFieldValence;
    private GenericComboBox mComboBoxRadical;

	public AtomLabelDialogBuilder(GenericDialogHelper dialogHelper, ExtendedMolecule mol, int atom) {
		mDialog = dialogHelper.createDialog("Atom Properties", this);
		mMol = mol;
		mAtom = atom;
		build();
		}

	private void build() {
        int[] hLayout = {8, GenericDialog.PREFERRED, 8, GenericDialog.PREFERRED, 8 };
		int[] vLayout = {8, GenericDialog.PREFERRED, 4, GenericDialog.PREFERRED,
                        12, GenericDialog.PREFERRED, 4, GenericDialog.PREFERRED,
                        12, GenericDialog.PREFERRED, 4, GenericDialog.PREFERRED,
                        12, GenericDialog.PREFERRED, 8};
        mDialog.setLayout(hLayout, vLayout);

        mTextFieldLabel = mDialog.createTextField(1,1);
        mTextFieldLabel.setEventConsumer(this);
		mDialog.add(mDialog.createLabel("Atom Label:"), 1,1);
		mDialog.add(mTextFieldLabel, 3,1);
		mDialog.add(mDialog.createLabel("(examples: 'D', 'Li', 'Cys', 'R12', 'R3@C')"), 1,3,3,3);

        mTextFieldMass = mDialog.createTextField(1,1);
        mTextFieldMass.setEventConsumer(this);
		mDialog.add(mDialog.createLabel("Atom Mass:"), 1,5);
		mDialog.add(mTextFieldMass, 3,5);
		mDialog.add(mDialog.createLabel("(empty for natural abundance)"), 1,7,3,7);

        mTextFieldValence = mDialog.createTextField(1,1);
        mTextFieldValence.setEventConsumer(this);
		mDialog.add(mDialog.createLabel("Abnormal Valence:"), 1,9);
		mDialog.add(mTextFieldValence, 3,9);
		mDialog.add(mDialog.createLabel("(empty for default valence)"), 1,11,3,11);

        if (mAtom != -1) {
        	String label = mMol.getAtomLabel(mAtom);
        	String customLabel = mMol.getAtomCustomLabel(mAtom);
            mTextFieldLabel.setText(customLabel == null ? label : customLabel+"@"+label);
            if (mMol.getAtomMass(mAtom) != 0)
                mTextFieldMass.setText(""+mMol.getAtomMass(mAtom));
            if (mMol.getAtomAbnormalValence(mAtom) != -1)
                mTextFieldValence.setText(""+mMol.getAtomAbnormalValence(mAtom));
            }

		mComboBoxRadical = mDialog.createComboBox();
        for (String s:RADICAL_STATES)
	        mComboBoxRadical.addItem(s);
        if (mAtom != -1) {
        	int state = mMol.getAtomRadical(mAtom);
        	mComboBoxRadical.setSelectedIndex(state == Molecule.cAtomRadicalStateD ? 1 :
        									  state == Molecule.cAtomRadicalStateT ? 2 :
        									  state == Molecule.cAtomRadicalStateS ? 3 : 0);
        	}
		mDialog.add(mDialog.createLabel("Radical State:"), 1,13);
		mDialog.add(mComboBoxRadical, 3,13);

		mDialog.showDialog();
		}

	@Override
	public void dialogEventHappened(DialogEvent e) {
		if (e.getSource() instanceof JTextField) {
			processAtomLabel();
			}
		else if (e.getWhat() == DialogEvent.WHAT_CANCEL) {
			mDialog.disposeDialog();
			}
		else if (e.getWhat() == DialogEvent.WHAT_OK) {
			processAtomLabel();
			mDialog.disposeDialog();
			}
		}

	private void processAtomLabel() {
		String text = mTextFieldLabel.getText();
		String customLabel = null;

		if (text.length() != 0) {
			int index = text.indexOf('@');
			if (index != -1) {
				customLabel = text.substring(0, index);
				text = text.substring(index+1);
				}
			}

		if (text.length() != 0) {
			int atomicNo = Molecule.getAtomicNoFromLabel(text);
			if (atomicNo != 0 || text.equals("?")) {
			    int mass = 0;
			    if (mTextFieldMass.getText().length() != 0) {
    			    try {
    			        mass = Integer.parseInt(mTextFieldMass.getText());
    	                if (mass < Molecule.cRoundedMass[atomicNo] - 18
                         || mass > Molecule.cRoundedMass[atomicNo] + 12) {
    	                	mDialog.showMessage("Your mass is out of range!");
    	                    return;
    	                    }
    			        }
    			    catch (NumberFormatException nfe) {
				        mDialog.showMessage("Your mass is not a number!");
    			        return;
    			        }
			        }

                int valence = -1;
			    if (mTextFieldValence.getText().length() != 0) {
                    try {
                        valence = Integer.parseInt(mTextFieldValence.getText());
                        if (valence < 0 || valence > 15) {
	                        mDialog.showMessage("Your valence is out of range!");
                            return;
                            }
                        }
                    catch (NumberFormatException nfe) {
	                    mDialog.showMessage("Your valence is not a number!");
                        return;
                        }
                    }

                int	radical = mComboBoxRadical.getSelectedIndex() == 1 ? Molecule.cAtomRadicalStateD :
                			  mComboBoxRadical.getSelectedIndex() == 2 ? Molecule.cAtomRadicalStateT :
                   			  mComboBoxRadical.getSelectedIndex() == 3 ? Molecule.cAtomRadicalStateS : 0;

                mMol.changeAtom(mAtom, atomicNo, mass, valence, radical);
                if (customLabel != null)
                	mMol.setAtomCustomLabel(mAtom, customLabel);

                mDialog.disposeDialog();
			    }
			}
		}
	}
