package org.eclipse.jst.server.generic.ui.internal.editor;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jst.server.generic.core.internal.GenericServer;
import org.eclipse.jst.server.generic.core.internal.GenericServerRuntime;
import org.eclipse.jst.server.generic.servertype.definition.Property;
import org.eclipse.jst.server.generic.ui.internal.GenericServerUIMessages;
import org.eclipse.jst.server.generic.ui.internal.SWTUtil;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.wst.server.ui.editor.ServerEditorSection;

public class ServerPropertiesEditorSection extends ServerEditorSection{
	private GenericServer fServer;
	private PropertyChangeListener fPropertyChangeListener;
	private Map fControls = new HashMap();
    private boolean fUpdating;
    
	public void init(IEditorSite site, IEditorInput input) {
		super.init(site, input);
		if(server!=null){
			fServer = (GenericServer)server.loadAdapter(GenericServer.class, new NullProgressMonitor());
		}
		fPropertyChangeListener = new PropertyChangeListener(){

			public void propertyChange( PropertyChangeEvent evt ) {
				if(evt.getPropertyName().equals( GenericServerRuntime.SERVER_INSTANCE_PROPERTIES )) 
                {
                    if ( !fUpdating ){
                        fUpdating = true;
                        updateControls();
                        fUpdating = false;
                    }
                }
			}
		};
		server.addPropertyChangeListener( fPropertyChangeListener );
	}
    
	protected void updateControls() {
        List props = fServer.getServerDefinition().getProperty(); 
        for (Iterator iter = props.iterator(); iter.hasNext();) {
            Property property = (Property) iter.next();
            if(property.getContext().equals(Property.CONTEXT_SERVER))
            {
                if( Property.TYPE_BOOLEAN.equals(property.getType()) ){
                    Button b = (Button)fControls.get( property.getId() );
                    b.setSelection( "true".equals(  getPropertyValue( property ) ) ); //$NON-NLS-1$
                }
                else if( Property.TYPE_SELECT.equals( property.getType() )){
                    Combo c = (Combo)fControls.get( property.getId() );
                    String value = getPropertyValue( property )==null ? "": getPropertyValue( property ); //$NON-NLS-1$
                    //c.setText( getPropertyValue( property ) );
                    // responding to "value not used" msg, I'm assuming value
                    // should be used as in following block.
                    c.setText( value );
                }
                else{
                    Text t = (Text)fControls.get( property.getId() );
                    String value = getPropertyValue( property )==null ? "": getPropertyValue( property ); //$NON-NLS-1$
                    t.setText( value );
                }
            }
        }  
    }

    public void createSection(Composite parent) {
		super.createSection(parent);
		FormToolkit formToolkit = getFormToolkit(parent.getDisplay());
		Section section = formToolkit.createSection(parent, ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED
				| ExpandableComposite.TITLE_BAR | Section.DESCRIPTION | ExpandableComposite.FOCUS_TITLE);
			section.setText(GenericServerUIMessages.ServerEditorSectionTitle);
			section.setDescription(GenericServerUIMessages.ServerEditorSectionDescription);
			section.setLayoutData(new GridData(SWT.FILL,SWT.NONE,true,false));
			
		Composite composite = formToolkit.createComposite(section);
		GridLayout layout = new GridLayout();
		layout.numColumns=3;
		layout.marginHeight = 5;
		layout.marginWidth = 10;
		layout.verticalSpacing = 5;
		layout.horizontalSpacing = 15;
		composite.setLayout(layout);
		composite.setLayoutData(new GridData(SWT.FILL,SWT.NONE,true,false));
		
		List props = fServer.getServerDefinition().getProperty();
		for (Iterator iter = props.iterator(); iter.hasNext();) {
			Property property = (Property) iter.next();
			if(property.getContext().equals(Property.CONTEXT_SERVER))
				createPropertyControl(composite, property,formToolkit);
		}

		formToolkit.paintBordersFor(composite);
		section.setClient(composite);
	}
	
	private void executeUpdateOperation(String propertyName, String propertyValue)
	{
        if( !fUpdating )
        {
            fUpdating = true;
            execute( new UpdateServerPropertyOperation( server,
                    GenericServerUIMessages.UpdateOperationDescription, propertyName,
                    propertyValue ) );
            fUpdating = false;
        }
	}
    
    private void createPropertyControl(Composite parent, final Property property, FormToolkit toolkit){
    	
    	if( Property.TYPE_DIRECTORY.equals(property.getType())) {
    		final Text path = SWTUtil.createLabeledPath(property.getLabel(),getPropertyValue(property),parent,toolkit);
            fControls.put( property.getId(), path );
    		path.addModifyListener(new ModifyListener() {			
				public void modifyText(ModifyEvent e) {
					executeUpdateOperation(property.getId(),path.getText());
				}
			});
     	} else if( Property.TYPE_FILE.equals(property.getType())) {
            
    	    final Text file = SWTUtil.createLabeledFile(property.getLabel(),getPropertyValue(property),parent,toolkit);
    		fControls.put( property.getId(), file );
            file.addModifyListener(new ModifyListener() {
				public void modifyText(ModifyEvent e) {
					executeUpdateOperation(property.getId(),file.getText());
				}
			});	
       	}else if( Property.TYPE_BOOLEAN.equals(property.getType())) {
    	    final Button bool = SWTUtil.createLabeledCheck(property.getLabel(),("true".equals( getPropertyValue(property))),parent,toolkit); //$NON-NLS-1$
    	    fControls.put( property.getId(), bool );
            bool.addSelectionListener(new SelectionListener() {			
				public void widgetSelected(SelectionEvent e) {
					executeUpdateOperation(property.getId(),  Boolean.toString(bool.getSelection()));
				}
				public void widgetDefaultSelected(SelectionEvent e) {
					// Do Nothing
				}
			});	
       	}else if(Property.TYPE_SELECT.equals(property.getType())) {
    		StringTokenizer tokenizer = new StringTokenizer(property.getDefault(),","); //$NON-NLS-1$
    		int tokenCount = tokenizer.countTokens();
    		String[] values = new String[tokenCount];
    		int i =0;
    		while(tokenizer.hasMoreTokens() && i<tokenCount){
    			values[i]=tokenizer.nextToken();
    			i++;
    		}
       		final Combo combo = SWTUtil.createLabeledCombo(property.getLabel(), values, parent,toolkit);
       		fControls.put( property.getId(), combo );
            combo.addModifyListener(new ModifyListener() {
				public void modifyText(ModifyEvent e) {
					executeUpdateOperation(property.getId(),combo.getText());
				}
			});
       		combo.addSelectionListener(new SelectionListener() {		
				public void widgetSelected(SelectionEvent e) {
					executeUpdateOperation(property.getId(),combo.getText());
				}			
				public void widgetDefaultSelected(SelectionEvent e) {
					// nothing to do
				}			
			});	
       	}
       	else  {// Property.TYPE_TEXT
    	    final Text defaultText= SWTUtil.createLabeledText(property.getLabel(),getPropertyValue(property),parent,toolkit);
            fControls.put( property.getId(), defaultText );
    		defaultText.addModifyListener(new ModifyListener() {
				public void modifyText(ModifyEvent e) {
					executeUpdateOperation(property.getId(), defaultText.getText());
				}
			});
    	}
    }

	private String getPropertyValue(Property property) {
		 return(String) fServer.getServerInstanceProperties().get(property.getId());
	}

	public void dispose() {
	    super.dispose();
        if( server!= null )
            server.removePropertyChangeListener( fPropertyChangeListener );
	}
	
}
