/*******************************************************************************
 * Copyright (c) 2001, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.sse.ui.internal.extension;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuCreator;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.ListenerList;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.HelpListener;
import org.eclipse.swt.widgets.Event;
import org.eclipse.ui.texteditor.IUpdate;
import org.eclipse.wst.sse.ui.internal.IExtendedEditorAction;
import org.eclipse.wst.sse.ui.internal.IExtendedSimpleEditor;
import org.eclipse.wst.sse.ui.internal.Logger;
import org.osgi.framework.Bundle;

public class ExtendedEditorActionProxyForDelayLoading implements IExtendedEditorAction, IExtendedEditorActionProxyForDelayLoading, IAction {
    private IAction proxy;
    private IAction dummy = new Action() { // this is for mainly its property change notify...
    };
    // proxy'ed properties
    private String p_id;
    private boolean set_p_id;
    private String p_text;
    private boolean set_p_text;
    private String p_toolTipText;
    private boolean set_p_toolTipText;
    private String p_actionDefinitionId;
    private boolean set_p_actionDefinitionId;
    private ImageDescriptor p_image;
    private boolean set_p_image;
    private ImageDescriptor p_hoverImage;
    private boolean set_p_hoverImage;
    private ImageDescriptor p_disabledImage;
    private boolean set_p_disabledImage;
    private int p_accelerator;
    private boolean set_p_accelerator;
    private int p_style = AS_PUSH_BUTTON;
    //private boolean set_p_style;
    private HelpListener p_helpListener;
    private boolean set_p_helpListener;
    private boolean p_enabled = true; // should be same as what is done in
    private boolean set_p_enabled;
    private ListenerList p_listeners = new ListenerList(3);
    private boolean set_p_listeners;
    private boolean p_checked;
    private boolean set_p_checked;
    private IExtendedSimpleEditor p_targetEditor;
    private boolean set_p_targetEditor;
	private boolean p_isvisible = true; // should be true
	
	private IConfigurationElement element;
	private String classAttribute;

	 /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#addPropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
     */
    public void addPropertyChangeListener(IPropertyChangeListener listener) {
        p_listeners.add(listener);
        set_p_listeners = true;
        // don't realize class.
        // realize();
        if (proxy != null) {
            proxy.addPropertyChangeListener(listener);
        } else {
        	dummy.addPropertyChangeListener(listener);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#getAccelerator()
     */
    public int getAccelerator() {
        // don't realize class.
        // realize();
        if (proxy != null) {
            return proxy.getAccelerator();
        }
        return p_accelerator;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#getActionDefinitionId()
     */
    public String getActionDefinitionId() {
        // don't realize class.
        // realize();
        if (proxy != null) {
            return proxy.getActionDefinitionId();
        }
        return p_actionDefinitionId;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#getDescription()
     */
    public String getDescription() {
        //        System.out.println(p_id + ": getDescription");
        //        System.out.flush();
        realize();
        if (proxy != null) {
            return proxy.getDescription();
        }
        return null;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#getDisabledImageDescriptor()
     */
    public ImageDescriptor getDisabledImageDescriptor() {
        // don't realize class.
        // realize();
        if (proxy != null) {
            return proxy.getDisabledImageDescriptor();
        }
        return p_disabledImage;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#getHelpListener()
     */
    public HelpListener getHelpListener() {
        // don't realize class.
        // realize();
        if (proxy != null) {
            return proxy.getHelpListener();
        }
        return p_helpListener;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#getHoverImageDescriptor()
     */
    public ImageDescriptor getHoverImageDescriptor() {
        // don't realize class.
        // realize();
        if (proxy != null) {
            return proxy.getHoverImageDescriptor();
        }
        return p_hoverImage;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#getId()
     */
    public String getId() {
        // don't realize class.
        // realize();
        if (proxy != null) {
            return proxy.getId();
        }
        return p_id;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#getImageDescriptor()
     */
    public ImageDescriptor getImageDescriptor() {
        // don't realize class.
        // realize();
        if (proxy != null) {
            return proxy.getImageDescriptor();
        }
        return p_image;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#getMenuCreator()
     */
    public IMenuCreator getMenuCreator() {
        //        System.out.println(p_id + ": getMenuCreator");
        //        System.out.flush();
        realize();
        if (proxy != null) {
            return proxy.getMenuCreator();
        }
        return null;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#getStyle()
     */
    public int getStyle() {
        // don't realize class.
        // realize();
        if (proxy != null) {
            return proxy.getStyle();
        }
        return p_style;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#getText()
     */
    public String getText() {
        // don't realize class.
        // realize();
        if (proxy != null) {
            return proxy.getText();
        }
        return p_text;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#getToolTipText()
     */
    public String getToolTipText() {
        // don't realize class.
        // realize();
        if (proxy != null) {
            return proxy.getToolTipText();
        }
        return p_toolTipText;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#isChecked()
     */
    public boolean isChecked() {
        // don't realize class.
        // realize();
        if (proxy != null) {
            return proxy.isChecked();
        }
        return p_checked;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#isEnabled()
     */
    public boolean isEnabled() {
        // don't realize class.
        // realize();
        if (proxy != null) {
            return proxy.isEnabled();
        }
        return p_enabled;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#removePropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
     */
    public void removePropertyChangeListener(IPropertyChangeListener listener) {
        p_listeners.remove(listener);
        // don't realize class.
        // realize();
        if (proxy != null) {
            proxy.removePropertyChangeListener(listener);
        }
        dummy.removePropertyChangeListener(listener);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#run()
     */
    public void run() {
        realize();
        if (proxy != null) {
            // if this has a key accelerator, first update this action and to
            // see if this action is enabled or not.
            if ((proxy.getAccelerator() > 0) || (proxy.getActionDefinitionId() != null)) {
                update();
                if (isEnabled() == true) {
                    proxy.run();
                }
            } else {
                proxy.run();
            }
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#runWithEvent(org.eclipse.swt.widgets.Event)
     */
    public void runWithEvent(Event event) {
        realize();
        if (proxy != null) {
            // same as run()
            if ((proxy.getAccelerator() > 0) || (proxy.getActionDefinitionId() != null)) {
                update();
                if (isEnabled() == true) {
                    proxy.runWithEvent(event);
                }
            } else {
                proxy.runWithEvent(event);
            }
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#setActionDefinitionId(java.lang.String)
     */
    public void setActionDefinitionId(String id) {
        p_actionDefinitionId = id;
        set_p_actionDefinitionId = true;
        // don't realize class.
        // realize();
        if (proxy != null) {
            proxy.setActionDefinitionId(id);
        } else {
        	dummy.setActionDefinitionId(id);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#setChecked(boolean)
     */
    public void setChecked(boolean checked) {
        p_checked = checked;
        set_p_checked = true;
        // don't realize class.
        // realize();
        if (proxy != null) {
            proxy.setChecked(checked);
        } else {
        	dummy.setChecked(checked);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#setDescription(java.lang.String)
     */
    public void setDescription(String text) {
        //        System.out.println(p_id + ": setDescription");
        //        System.out.flush();
        realize();
        if (proxy != null) {
            proxy.setDescription(text);
        } else {
        	dummy.setDescription(text);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#setDisabledImageDescriptor(org.eclipse.jface.resource.ImageDescriptor)
     */
    public void setDisabledImageDescriptor(ImageDescriptor newImage) {
        p_disabledImage = newImage;
        set_p_disabledImage = true;
        // don't realize class.
        // realize();
        if (proxy != null) {
            proxy.setDisabledImageDescriptor(newImage);
        } else {
        	dummy.setDisabledImageDescriptor(newImage);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#setEnabled(boolean)
     */
    public void setEnabled(boolean enabled) {
        p_enabled = enabled;
        set_p_enabled = true;
        // don't realize class.
        // realize();
        if (proxy != null) {
            proxy.setEnabled(enabled);
        } else {
        	dummy.setEnabled(enabled);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#setHelpListener(org.eclipse.swt.events.HelpListener)
     */
    public void setHelpListener(HelpListener listener) {
        p_helpListener = listener;
        set_p_helpListener = true;
        // don't realize class.
        // realize();
        if (proxy != null) {
            proxy.setHelpListener(listener);
        } else {
        	dummy.setHelpListener(listener);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#setHoverImageDescriptor(org.eclipse.jface.resource.ImageDescriptor)
     */
    public void setHoverImageDescriptor(ImageDescriptor newImage) {
        p_hoverImage = newImage;
        set_p_hoverImage = true;
        // don't realize class.
        // realize();
        if (proxy != null) {
            proxy.setHoverImageDescriptor(newImage);
        } else {
        	dummy.setHoverImageDescriptor(newImage);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#setId(java.lang.String)
     */
    public void setId(String id) {
        p_id = id;
        set_p_id = true;
        // don't realize class.
        // realize();
        if (proxy != null) {
            proxy.setId(id);
        } else {
        	dummy.setId(id);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#setImageDescriptor(org.eclipse.jface.resource.ImageDescriptor)
     */
    public void setImageDescriptor(ImageDescriptor newImage) {
        p_image = newImage;
        set_p_image = true;
        // don't realize class.
        // realize();
        if (proxy != null) {
            proxy.setImageDescriptor(newImage);
        } else {
        	dummy.setImageDescriptor(newImage);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#setMenuCreator(org.eclipse.jface.action.IMenuCreator)
     */
    public void setMenuCreator(IMenuCreator creator) {
        //        System.out.println(p_id + ": setMenuCreator");
        //        System.out.flush();
        realize();
        if (proxy != null) {
            proxy.setMenuCreator(creator);
        } else {
        	dummy.setMenuCreator(creator);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#setText(java.lang.String)
     */
    public void setText(String text) {
        p_text = text;
        set_p_text = true;
        // don't realize class.
        // realize();
        if (proxy != null) {
            proxy.setText(text);
        } else {
        	dummy.setText(text);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#setToolTipText(java.lang.String)
     */
    public void setToolTipText(String text) {
        p_toolTipText = text;
        set_p_toolTipText = true;
        // don't realize class.
        // realize();
        if (proxy != null) {
            proxy.setToolTipText(text);
        } else {
        	dummy.setToolTipText(text);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#setAccelerator(int)
     */
    public void setAccelerator(int keycode) {
        p_accelerator = keycode;
        set_p_accelerator = true;
        // don't realize class.
        // realize();
        if (proxy != null) {
            proxy.setAccelerator(keycode);
        } else {
        	dummy.setAccelerator(keycode);
        }
    }


	/* (non-Javadoc)
	 * @see org.eclipse.wst.sse.ui.internal.IExtendedEditorAction#setActiveExtendedEditor(com.ibm.sse.editor.extension.IExtendedSimpleEditor)
	 */
	public void setActiveExtendedEditor(IExtendedSimpleEditor targetEditor) {
		p_targetEditor = targetEditor;
		set_p_targetEditor = true;
        // don't realize class.
        // realize();
        if ((proxy != null) && (proxy instanceof IExtendedEditorAction)) {
            ((IExtendedEditorAction)proxy).setActiveExtendedEditor(targetEditor);
        }
	}

	/* (non-Javadoc)
	 * @see com.ibm.sse.editor.extension.IExtendedEditorAction#isVisible()
	 */
	public boolean isVisible() {
        // don't realize class.
        // realize();
        if ((proxy != null) && (proxy instanceof IExtendedEditorAction)) {
            return ((IExtendedEditorAction)proxy).isVisible();
        }
        return p_isvisible;
	}

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.action.IAction#isHandled
     */
	public boolean isHandled() {
		return false;
	}

	// see ActionDescriptor#createExtension
	private static IAction newInstance(final IConfigurationElement elm, final String cla) {
		final Object[] result = new Object[1];
		// If plugin has been loaded create extension.
		// Otherwise, show busy cursor then create extension.
		Bundle bundle= Platform.getBundle(elm.getDeclaringExtension().getNamespace());
		if (bundle != null && bundle.getState() == Bundle.ACTIVE) {
			try {
				result[0] = elm.createExecutableExtension(cla);
			}
			catch (Exception e) {
				// catch and log ANY exception from extension point
				handleCreateExecutableException(result, e);
			}
		}
		else {
			BusyIndicator.showWhile(null, new Runnable() {
				public void run() {
					try {
						result[0] = elm.createExecutableExtension(cla);
					}
					catch (Exception e) {
						// catch and log ANY exception from extension point
						handleCreateExecutableException(result, e);
					}
				}
			});
		}
		if ((result[0] != null) && (result[0] instanceof IAction)) {
			return (IAction)result[0];
		}
		return null;
    }
	
	private static void handleCreateExecutableException(final Object[] result, Throwable e) {
		Logger.logException(e);
		result[0] = null;
	}

	/**
     * Instantiate a real class here
     */
    public void realize() {
        if ((proxy == null) && (element != null) && (classAttribute != null)) {
            proxy = newInstance(element, classAttribute);
	        if (proxy != null) {
	            element = null;
	            classAttribute = null;
	            // propagate proxy'ed properties
	            if (set_p_listeners == true) {
	                if (p_listeners.size() > 0) {
	                    Object[] l = p_listeners.getListeners();
	                    int ls = l.length;
	                    for (int i = 0; i < ls; i++) {
	                        IPropertyChangeListener pl = (IPropertyChangeListener) l[i];
	                        proxy.addPropertyChangeListener(pl);
	                        dummy.removePropertyChangeListener(pl); // remove listener from dymmy so that we don't send notifications twice anymore
	                    }
	                }
	            }
	            if (set_p_accelerator == true) {
	                proxy.setAccelerator(p_accelerator);
	            }
	            if (set_p_actionDefinitionId == true) {
	                if (p_actionDefinitionId != null) {
	                    proxy.setActionDefinitionId(p_actionDefinitionId);
	                }
	            }
	            if (set_p_checked == true) {
	                proxy.setChecked(p_checked);
	            }
	            if (set_p_disabledImage == true) {
	                if (p_disabledImage != null) {
	                    proxy.setDisabledImageDescriptor(p_disabledImage);
	                }
	            }
	            if (set_p_enabled == true) {
	                proxy.setEnabled(p_enabled);
	            }
	            if (set_p_helpListener == true) {
	                if (p_helpListener != null) {
	                    proxy.setHelpListener(p_helpListener);
	                }
	            }
	            if (set_p_hoverImage == true) {
	                if (p_hoverImage != null) {
	                    proxy.setHoverImageDescriptor(p_hoverImage);
	                }
	            }
	            if (set_p_id == true) {
	                if (p_id != null) {
	                    proxy.setId(p_id);
	                }
	            }
	            if (set_p_image == true) {
	                if (p_image != null) {
	                    proxy.setImageDescriptor(p_image);
	                }
	            }
	            if (set_p_text == true) {
	                if (p_text != null) {
	                    proxy.setText(p_text);
	                }
	            }
	            if (set_p_toolTipText == true) {
	                if (p_toolTipText != null) {
	                    proxy.setToolTipText(p_toolTipText);
	                }
	            }
	            if (set_p_targetEditor == true) {
	                if (p_targetEditor != null) {
				        if (proxy instanceof IExtendedEditorAction) {
				            ((IExtendedEditorAction)proxy).setActiveExtendedEditor(p_targetEditor);
				        }
	                }
	            }
	        }
        }
    }

    public boolean isRealized() {
        return (proxy != null);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.texteditor.IUpdate#update()
     */
    public void update() {
        // don't realize class.
        // realize();
        if ((proxy != null) && (proxy instanceof IUpdate)) {
            ((IUpdate) proxy).update();
        }
    }

    /**
     * get a real action class
     */
    public IAction getAction() {
        realize();
        return proxy;
    }


    /**
     * These are Actions's constructors
     */
    ExtendedEditorActionProxyForDelayLoading() {
        super();
     }
    public ExtendedEditorActionProxyForDelayLoading(final IConfigurationElement element, final String classAttribute) {
        super();
        this.element = element;
        this.classAttribute = classAttribute;
    }
}
