/*-------------------------------------------------------------------------------
Copyright (c)2000 TogetherSoft Corporation. Patents pending. All rights reserved.
-------------------------------------------------------------------------------*/

package com.togethersoft.modules.tutorial;

import com.togethersoft.openapi.ide.IdeContext;
import com.togethersoft.openapi.ide.IdeScript;
import com.togethersoft.openapi.ide.IdeStartup;
import com.togethersoft.openapi.ide.message.IdeMessageManagerAccess;
import com.togethersoft.openapi.ide.message.IdeMessageType;
import com.togethersoft.openapi.ide.command.IdeCommandManagerAccess;
import com.togethersoft.openapi.ide.command.IdeCommandManager;
import com.togethersoft.openapi.ide.command.IdeCommandAdapter;
import com.togethersoft.openapi.ide.command.IdeCommandCheckListener;
import com.togethersoft.openapi.ide.command.IdeCommandConstraints;
import com.togethersoft.openapi.ide.command.IdeCommandItem;
import com.togethersoft.openapi.ide.command.IdeCommandGroup;
import com.togethersoft.openapi.ide.command.IdeCommandEvent;
import com.togethersoft.openapi.rwi.RwiModelAccess;
import com.togethersoft.openapi.rwi.RwiNode;
import com.togethersoft.openapi.rwi.RwiMember;
import com.togethersoft.openapi.rwi.RwiShapeType;
import com.togethersoft.openapi.rwi.RwiProperty;
import com.togethersoft.openapi.rwi.RwiElement;
import com.togethersoft.openapi.rwi.enum.RwiMemberEnumeration;

/**
 * This module shows how to add custom menus and commands
 * to the element's popup menu.
 *
 * It creates a submenu called "My menu" with commands "Show the qualified name"
 * (outputs the qualified name) and "Simple action" (outputs the "Hello" string).
 *
 * Note the difference with the previous lesson: this module does not rely on the
 * "PopupMenuItem = true" command in the module's manifest file, but builds the
 * submenu and the commands by itself. This requires some effort but allows
 * to control the behavior of the command and submenu more flexibly.
 *
 * To demonstrate this let's make the menu "My menu" appear only for classes
 * and interfaces:
 * 1. for classes its name must be "My menu (for classes)"
 * 2. for interfaces its name must be "My menu (for interfaces)"
 *
 * Moreover, the command "Show the qualified name" must:
 * 1. be disabled for interfaces containing declared methods and its
 *    name must be "Show the qualified name
 *    (not implemented for interfaces with methods yet)"
 * 2. be hidden for interfaces with no declared methods.
 * 3. be enabled for classes, the name should be "Show the qualified name"
 *    for public classes and "Show the qualified name (package local class)"
 *    for the classes with the default access level.
 *
 * The command "Simple action" should be located after the
 * "Show the qualified name" command.
 *
 * This module implements both IdeScript and IdeStartup intrefaces, which makes
 * it a regular and a startup module simultaneously. To run it as a startup module,
 * the line "Time = Startup" in the tutorial modules manifest file. This will
 * create the described submenu each time you run Together.
 *
 * You can use the contents of the createTheMenu method as a template
 * for creating your own menus.
 *
 * Note: if you use 800x600 resolution you might have some problems seeing
 * the menu since is placed at the end of a popup menu which already contains
 * too many commands (try to place a class at the top of a diagram or try
 * to use the 1024x768 for this module)
 *
 * @author TogetherSoft
 */
public class Lesson06 implements IdeScript, IdeStartup
{
   /**
    * Runs this module.
    *
    * @param context the IdeContext instance containing
    * the selection information at the moment the module was called.
    */
    public void run(IdeContext context)
    {
        // printing message into message pane
        IdeMessageManagerAccess.printMessage
            (IdeMessageType.INFORMATION, "Lesson06 module: started");

        // menu creation
        createTheMenu();

        // printing final message
        IdeMessageManagerAccess.printMessage
            (IdeMessageType.INFORMATION, "Lesson06 module: finished");
    }

    /**
    * This method is called while Together is loading.
    */
    public void autorun()
    {
        // creation menu in processs of Together loading (startup).
        createTheMenu();
    }

    /**
     * Creates popup menu (adding menus and command in popup menu)
     */
    private void createTheMenu()
    {
        // getting IdeCommandManager object
        IdeCommandManager cman = IdeCommandManagerAccess.getCommandManager();

        // create a new command group which can be used as a container
        // for other command items
        myGroup = cman.createGroup
            ("IDOfTheGroup", // identifier

            // constraint object witch defines constraints for the command items
            new IdeCommandConstraints
            ("context = element, shapeType=Class, location=popupMenu"),
            // Now, the constraints mechanism works so, that it will run
            // checkStatus method (below) only, if the shapetype of the element
            // equals the specified value "Class" ( for classes and interfaces ).

            // listener object for receiving command events from items and groups
            new IdeCommandCheckListener()
            {
                public void checkStatus(IdeCommandEvent event)
                {
                    // getting the element(s) under cursor

                    // getting context
                    IdeContext context = event.getElementContext();

                    // getting array of selected elements from context
                    RwiElement[] selectedRwiElements = context.getRwiElements();

                    // getting selected element
                    RwiElement theElement = selectedRwiElements[0];

                    // set group text
                    // if it's an intercace
                    if (theElement.hasProperty(RwiProperty.INTERFACE))
                    {
                        event.getCommandItem().setText("My menu (for interfaces)");
                    }
                    else // it's a class
                    {
                        event.getCommandItem().setText("My menu (for classes)");
                    }
                }
            });

        // Note that in the following line we do not specify the shapetype,
        // because it is specified in the group's constraints. For elements
        // with the shapetype other than RwiShapeType.CLASS, the group will be
        // invisible, as well all the items contained in it

        // create first item
        myItem = cman.createItem
            ("IDOfTheItem", // identifier

            // constraint object witch defines constraints for the command items
            new IdeCommandConstraints
            ("context = element, parent=IDOfTheGroup, location=popupMenu"),

            // IdeCommandAdapter object
            new IdeCommandAdapter()
            {
                public void checkStatus(IdeCommandEvent event)
                {
                    //getting the element(s) under the cursor
                    IdeContext context = event.getElementContext();
                    RwiElement[] selectedRwiElements = context.getRwiElements();
                    RwiElement theElement = selectedRwiElements[0];

                    IdeCommandItem item = event.getCommandItem();

                    // if it's interface
                    if (theElement.hasProperty(RwiProperty.INTERFACE))
                    {
                        // gettings enumeration of members
                        RwiMemberEnumeration members = ((RwiNode)theElement).members();

                        int methodsCount = 0;  // method counter

                        // counting the declared methods
                        while (members.hasMoreElements())
                        {
                            // getting current member
                            RwiMember nextMember = members.nextRwiMember();
                            // if appropriate shapetype
                            if (RwiShapeType.OPERATION.equals(nextMember.getProperty(RwiProperty.SHAPE_TYPE)))
                                methodsCount++;
                        }

                        // if there are methods
                        if (methodsCount != 0)
                        {
                            // set item visible
                            // this is required because we might have hidden it (the 4 lines below)
                            item.setVisible(true);
                            item.setEnabled(false); // disable item
                            item.setText("Show the qualified name (not implemented for interfaces with methods yet)");
                        }
                        else  // ther are not methods
                        {
                            // set item invisible
                            item.setVisible(false);
                        }
                    }
                    else // it's class
                    {
                        item.setEnabled(true);  // enable item
                        item.setVisible(true);  // set item visible

                        // if the class is public
                        if (theElement.hasProperty(RwiProperty.PUBLIC))
                        {
                            item.setText("Show the qualified name");
                        }
                        // if the class is package local
                        else if (theElement.hasProperty(RwiProperty.PACKAGE_LOCAL))
                        {
                            item.setText("Show the qualified name (package local class)");
                        }
                    }
                }

                // the user managed to invoke the command
                public void actionPerformed(IdeCommandEvent event)
                {
                    // getting the element under cursor
                    IdeContext context = event.getElementContext();
                    RwiElement[] selectedRwiElements = context.getRwiElements();
                    RwiElement rwiElement = selectedRwiElements[0];

                    // making message pane visible
                    IdeMessageManagerAccess.getMessageManager().setPaneVisible(true); //making the message pane visible

                    // printing message
                    IdeMessageManagerAccess.printMessage
                        (IdeMessageType.INFORMATION,
                        "Lesson06: the qualified name is " +
                        rwiElement.getProperty(RwiProperty.FULL_NAME));
                }
            });

        // create second item
        // Note: the "placeAfter" parameter, there we specify the ID of the myItem
        myItem2 = cman.createItem
            ("IDOfTheItem2",
            new IdeCommandConstraints
            ("context = element, parent=IDOfTheGroup, placeAfter = IDOfTheItem, location=popupMenu"),
            new IdeCommandAdapter()
            {
                // The item is always visible, so
                // we use the empty checkStatus method.

                // the user managed to invoke the command
                public void actionPerformed(IdeCommandEvent event)
                {
                    // making message pane visible
                    IdeMessageManagerAccess.getMessageManager().setPaneVisible(true);

                    // printing message
                    IdeMessageManagerAccess.printMessage
                        (IdeMessageType.INFORMATION, "Lesson06: Hello");
                }
            });
        myItem2.setText("Simple action"); // set item text

        // making message pane visible
        IdeMessageManagerAccess.getMessageManager().setPaneVisible(true);

        // printing message
        IdeMessageManagerAccess.printMessage(IdeMessageType.INFORMATION,
            "Lesson06 module: new popup submenu for classes/interfaces was successfully created.");
    }

    private IdeCommandGroup myGroup; // command group
    private IdeCommandItem myItem;   // command item
    private IdeCommandItem myItem2;  // command item
}




