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() ) ||  Property.TYPE_SELECT_EDIT.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 if(Property.TYPE_SELECT_EDIT.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.createLabeledEditableCombo(property.getLabel(), values,getPropertyValue(property), 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 );
	}
	
}
