/*******************************************************************************
 * Copyright (c) 2001, 2005 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;
    }
}
