/*-------------------------------------------------------------------------------
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.message.IdeMessageManager;
import com.togethersoft.openapi.ide.message.IdeMessageManagerAccess;
import com.togethersoft.openapi.ide.message.IdeMessagePage;
import com.togethersoft.openapi.ide.message.IdeMessageType;
import com.togethersoft.openapi.ide.project.IdeProjectManagerAccess;
import com.togethersoft.openapi.rwi.RwiModelAccess;
import com.togethersoft.openapi.rwi.RwiNode;
import com.togethersoft.openapi.rwi.RwiMember;
import com.togethersoft.openapi.rwi.RwiLink;
import com.togethersoft.openapi.rwi.RwiDiagram;
import com.togethersoft.openapi.rwi.RwiShapeType;
import com.togethersoft.openapi.rwi.RwiPackage;
import com.togethersoft.openapi.rwi.RwiProperty;
import com.togethersoft.openapi.rwi.RwiElement;
import com.togethersoft.openapi.rwi.RwiModel;
import com.togethersoft.openapi.rwi.enum.RwiNodeEnumeration;
import com.togethersoft.openapi.rwi.enum.RwiPackageEnumeration;

/**
 * This module shows how to iterate the model.
 * It starts from the root packages and iterates their subpackages
 * showing the hierarchy of packages in the model.
 * You can use this example as a template for your model-iterating modules.
 *
 * @author TogetherSoft
 */
public class Lesson04 implements IdeScript
{
   /**
    * 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 information message into message pane
        IdeMessageManagerAccess.printMessage
            (IdeMessageType.INFORMATION, "Lesson04 module: started");

        // checking if project was opened
        if (IdeProjectManagerAccess.getProjectManager().getActiveProject() == null)
        {
            // project was not opened
            IdeMessageManagerAccess.printMessage
                (IdeMessageType.ERROR_MODAL, "No open project");
            IdeMessageManagerAccess.printMessage
                (IdeMessageType.INFORMATION, "Lesson04 module: finished");
            return;
        }

        // getting RWI model object
        RwiModel model = RwiModelAccess.getModel();

        // getting roots packages enumeration
        RwiPackageEnumeration roots = model.rootPackages(RwiProperty.MODEL);

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

        // printing information message
        IdeMessageManagerAccess.printMessage
            (IdeMessageType.INFORMATION, "The heirarchy of packages:");

        // processing all packages
        while (roots.hasMoreElements())
        {
            // getting package
            RwiPackage nextRootPackage = roots.nextRwiPackage();
            // processing root package
            packageProcessing(nextRootPackage, 0);
        }

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

    /**
     * This method recursively performs the same action upon the RwiPackage
     * passed to it as an argument and upon all its subpackages.
     *
     * @param rwiPackage specified RwiPackage object
     * @param depth "depth" of package level
     */
    private void packageProcessing(RwiPackage rwiPackage, int depth)
    {
        // Put the desired actions in this method.
        // The second argument is used only for this sample module.
        doActionUponPackage(rwiPackage, depth);

        // getting all subpackages enumeration
        RwiPackageEnumeration subPackages = rwiPackage.subpackages();

        // processing each subpackage
        while (subPackages.hasMoreElements())
        {
            // getting subpackage
            RwiPackage nextPackage = subPackages.nextRwiPackage();
            // processing subpackage
            packageProcessing(nextPackage, depth + 1);
        }
    }

    /**
     * This method perfoms certain actions upon the RwiPackage
     * passed to it as an argument.
     * In this method, for example, you can get and analyze all the nodes
     * or diagrams in the package etc.
     *
     * @param rwiPackage specified RwiPackage object
     * @param depth "depth" of package level
     */
    private void doActionUponPackage(RwiPackage rwiPackage, int depth)
    {
        // output the name of the package
        StringBuffer temp = new StringBuffer();
        for (int i = 0; i < depth; i++)
        {
            temp.append("  ");
        }

        // if it's root package
        if (depth == 0)
        {
            IdeMessageManagerAccess.printMessage
                (IdeMessageType.INFORMATION, "Root package");
            // note - for root packages RwiProperty.FULL_NAME is ""
        }
        else // not root package
        {
            IdeMessageManagerAccess.printMessage(IdeMessageType.INFORMATION,
                temp.toString() + rwiPackage.getProperty(RwiProperty.FULL_NAME));
        }

        // do some actions upon all the classes/interfaces in this package

        // getting RWI nodes enumeration in this package
        RwiNodeEnumeration nodes = rwiPackage.nodes();

        // processing each node
        while (nodes.hasMoreElements())
        {
            // getting node
            RwiNode nextNode = nodes.nextRwiNode();
            // processing node
            doActionUponNode(nextNode);
        }
    }

    /**
     * This method perfoms certain actions upon the RwiNode
     * representing a class/interfaces.
     *
     * @param rwiNode specified RwiNode object
     * @param depth "depth" of package level
     */
    private void doActionUponNode(RwiNode node)
    {
        // is it class or interface ?
        if (RwiShapeType.CLASS.equals(node.getProperty(RwiProperty.SHAPE_TYPE)))
        {
            // is it interface
            if (node.hasProperty(RwiProperty.INTERFACE))
            {
                // Put the desired actions for interfaces here.
            }
            else // it's class
            {
                // It is a class.
                // Put the desired actions for classes here.
            }
        }
    }
}


