/******************************************************************************
 * Copyright by Telelogic AB 1999
 *
 *  This Program is owned by Telelogic and is protected by national 
 * copyright laws and international copyright treaties. Telelogic 
 * grants you the right to use this Program on one computer or in 
 * one local computer network at any one time. 
 * Under this License you may only modify the source code for the purpose 
 * of adapting it to your environment. You must reproduce and include 
 * any copyright and trademark notices on all copies of the source code. 
 * You may not use, copy, merge, modify or transfer the Program except as
 * provided in this License.
 * Telelogic does not warrant that the Program will meet your
 * requirements or that the operation of the Program will be
 * uninterrupted and error free. You are solely responsible that the
 * selection of the Program and the modification of the source code 
 * will achieve your intended results and that the results are actually 
 * obtained.
 *****************************************************************************/


#include "msctrace.h"
#include <stdio.h>
#include <stdlib.h>


/*
  The following defines affects the way teh application behaves.
  Change your makefile in order to observe the effects.

  INTERACTIVE          The application expects you to press <ENTER>
                       in order to perform the next action. Good to
                       have defined together with MSCEONLINETRACE
                       when observing which symbol each function produces.

  MSCEONLINETRACE      The application starts the MSC Editor/Tracer and directs
                       it's output to the MSC Editor/Tracer. If You do not want
                       to run at full speed use togheter with INTERACTIVE.

  TIMEONSYMBOLS        Provides the time parameter in each trace function
                       with an increasing value. This value can then be viewed
                       in the Info Window of the MSC Editor/Tracer.

  LOADINGANDCLEARING   Enables the code that demonstrates loading of
                       an MSC Diagram (GR or PR). The code also demonstrates
                       the clearing of a diagram.

  SEMANTICS_OK         Enables code that shows syntactically and
                       sematically correct use of the trace interface.

  IDENTIFIER_DEMO      Enables the code that shows the importance of
                       using identifiers when sending and receiving
                       messages. It also shows how object identifiers can
                       be saved, in order to show the object later.

  SEMANTICS_WRONG      Enables the code that shows syntactically correct
                       use of the interface, but with wrong semantics.
                       Enabling this section migh help you understand
                       error messages that are shown.

  INTERFACE_VIOLATIONS Enables the code that shows what happens if
                       incorrect parameters are sent to the trace
                       functions.

  ALLSECTIONS          Enables code that corresponds to defining
                       SEMANTICS_OK, IDENTIFIER_DEMO, SEMANTICS_WRONG and
                       INTERFACE_VIOLATIONS.

  ONLINEDEMO           Enables code that corresponds to defining
                       MSCEONLINETRACE, TIMEONSYMBOLS and INTERACTIVE.
  */



/* MACROS USED TO CHANGE THE BEHAVIOUR */

#ifdef ALLSECTIONS
#define SEMANTICS_OK
#define IDENTIFIER_DEMO
#define SEMANTICS_WRONG
#define INTERFACE_VIOLATIONS
#endif /* ALLSECTIONS */


#ifdef ONLINEDEMO
#define MSCEONLINETRACE
#define TIMEONSYMBOLS
#define INTERACTIVE
#endif /* ONLINEDEMO */


#ifdef TIMEONSYMBOLS
#define TIME timeEmulator ()
#else
#define TIME NULL
#endif

#ifdef INTERACTIVE
#define ENTER() getchar()
#else
#define ENTER()
#endif

static char* timeEmulator (void)
{
  /* NOTE:
     This function is NOT Multi-Thread Safe */
     
  static char timeString[30];
  static double eTime = 0;

  sprintf (timeString, "%f", eTime);
  eTime = eTime + 0.1;
  return timeString;
}


int main (int argc, char* argv[])
{
  MTDiagram diagram = NULL;

#ifdef INTERACTIVE
  printf ("Please press the <ENTER> key to perform each next action."
          "\n\n");
#endif

  printf ("Start trace or connect to the MSCE\n");
  ENTER ();
  
  
#ifdef MSCEONLINETRACE
  if (!MTStartMSCDiagram (&diagram, "Test", NULL)) {
#else
  if (!MTStartMSCDiagram (&diagram, "Test", "trace.mpr")) {
#endif
    printf ("Start of MSCE Failed 1 ......\n");
    if (NULL != diagram) {
      MTErrId error = MTGetLastError (diagram);
      printf ("%s\n", MTGetLastErrorStr (diagram));
#ifdef MSCEONLINETRACE
      printf ("PM Error code: %d\n", MTGetLastPMError (diagram));
      if (NULL != MTGetLastPMErrorStr (diagram)) {
        printf ("%s\n", MTGetLastPMErrorStr (diagram));
      }      
#endif
      switch (error) {
      case StartingPostMasterFailed:
        break;
        
      case StartingMSCEFailed:
        MTDisconnect ();
        break;
        
      case CreatingMSCDiagramFailed:
        /* We need to terminate the MSCE here since it is running but
           has no Window. It is thus impossible for a user to terminate
           the MSCE in a normal way
           */
        MTTerminateMSCE (&diagram);
        MTDisconnect  ();
      } 
    }
    else {
      printf ("Memory could not be allocated" );
    }

    printf ("Terminating");  
    ENTER ();  
    exit (1);
  }
  
  MTShowDiagram (diagram);  /* NB. */
  printf ("MSCE started\n");


#ifdef LOADINGANDCLEARING
  {
    MTDiagram loadedDiagram;
    /* NOTE:
       Change the path to an actual file, with an syntax that
       corresponds to your operating system. You may load both an
       .mpr file and a .msc file */
    char *diagramPath = "x:\\TestMap\\mpr-test\\ALT_inline.mpr";
    
    printf ("MTLoadMSC_File: %s\n", diagramPath);
    ENTER ();    
    MTLoadMSC_File (&loadedDiagram, diagramPath);
    MTShowDiagram (loadedDiagram);  /* NB. */
    printf ("MSCE started\n\n");

    printf ("Clear Diagram\n");
    ENTER ();
    MTClearDiagram (loadedDiagram);
    MTShowDiagram (loadedDiagram);  /* NB. (Also Updates the Viewport)*/

    MTEndMSCDiagram (&loadedDiagram); /* release resources */
  }
#endif



#ifdef SEMANTICS_OK

  printf ("Section SEMANTICS_OK\n"
          "--------------------\n\n");
  

  /* INSTANCE */
  /* INSTANCE */ /* Instance Kind */
  printf ("Normal instance:\n"
          "a: instance;\n");
  ENTER ();
  MTInstanceHead (diagram, "a", NULL, NULL, NULL, NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Instance with instance kind:\n"
          "b: instance bKind;\n");
  ENTER ();  
  MTInstanceHead (diagram, "b", NULL, NULL, "bKind", NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Instance with instance kind and kind denominator:\n"
          "c: instance process cKind;\n");
  ENTER ();
  MTInstanceHead (diagram, "c", "process", NULL, "cKind",
                  NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Instance with instance kind and qualifier:\n"
          "d: instance <<qualifier>> dKind;\n");
  ENTER ();
  MTInstanceHead (diagram, "d", NULL, "qualifier", "dKind",
                  NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Instance with instance kind, kind denominator and qualifier:\n"
          "e: instance process <<qualifier>> eKind;\n");
  ENTER ();
  MTInstanceHead (diagram, "e", "process", "qualifier", "eKind",
                  NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  /* INSTANCE */
  /* INSTANCE */ /* Decomposition */
  printf ("Decomposed Instance:\n"
          "f: instance decomposed;\n");
  ENTER ();
  MTInstanceHead (diagram, "f", NULL, NULL, NULL, "", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Instance decomposed as another instance:\n"
          "g: instance decomposed as h;\n");
  ENTER ();
  MTInstanceHead (diagram, "g", NULL, NULL, NULL, "h", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  /* INSTANCE */
  /* INSTANCE */ /* Comments */
  printf ("Instance with empty comment:\n"
          "i: instance comment '';\n");
  ENTER ();
  MTInstanceHead (diagram, "i", NULL, NULL, NULL, NULL, " ", TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Instance with comment:\n"
          "j: instance comment 'comment';\n");
  ENTER ();
  MTInstanceHead (diagram, "j", NULL, NULL, NULL, NULL, "comment", TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Instance with comment that has a newline:\n"
          "k: instance comment 'comment line1\\nline2';\n");
  ENTER ();
  MTInstanceHead (diagram, "k", NULL, NULL, NULL, NULL,
                  "comment line1\nline2", TIME, NULL);
  MTShowLastObject (diagram, false);
  
  printf ("Instance with comment with quotes:\n"
          "l: instance comment 'comment with quote ('').';\n");
  ENTER ();
  MTInstanceHead (diagram, "l", NULL, NULL, NULL, NULL,
                  "comment with quote ('').", TIME, NULL);
  MTShowLastObject (diagram, false);

  /* INSTANCE */
  /* INSTANCE */ /* Instance Createation */
  /* NOTE: The created instance is created (internally) by calling
     MTInstanceHead, so we do not redo all the combinations here,
     instead we concentrate on the new elements */
  printf ("Creation of a new Instnace"
          "m: instance;\n"
          "l: create m;\n");
  ENTER ();
  MTCreateInstance (diagram,
                    "l", NULL, NULL, TIME, NULL, /* creating Inst. */
                    "m", NULL, NULL, NULL, NULL, NULL, TIME, NULL); /*created*/
  MTShowLastObject (diagram, false);

  printf ("Creation of a new instance with paramenters"
          "n: instance;\n"
          "l: create n (1, 2, 3);\n");
  ENTER ();
  MTCreateInstance (diagram,
                    "l", "1, 2, 3", NULL, TIME, NULL, /* creating Inst. */
                    "n", NULL, NULL, NULL, NULL, NULL, TIME, NULL); /*created*/
  MTShowLastObject (diagram, false);

  printf ("Creation of a new instance with paramenters and comment"
          "n: instance;\n"
          "l: create o (1, 2, 3) comment 'comment';\n");
  ENTER ();
  MTCreateInstance (diagram,
                    "l", "1, 2, 3", "comment", TIME, NULL, /* creating Inst. */
                    "o", NULL, NULL, NULL, NULL, NULL, TIME, NULL); /*created*/
  MTShowLastObject (diagram, false);


  /* INSTANCE END*/
  /* INSTANCE END*/
  printf ("Ending an instance:\n"
          "a: endinstance;\n");
  ENTER ();
  MTInstanceEnd  (diagram, "a", NULL, TIME, NULL); 
  MTShowLastObject (diagram, false);

  printf ("Ending an instance with a comment:\n"
          "b: endinstance comment 'comment';\n");
  ENTER ();
  MTInstanceEnd  (diagram, "b", "comment", TIME, NULL); 
  MTShowLastObject (diagram, false);


  /* INSTANCE STOP */
  /* INSTANCE STOP */
  printf ("Stopping an instance:\n"
          "c: stop;\n");
  ENTER ();
  MTStopInstance (diagram, "c", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Stopping an instance with a comment:\n"
          "d: stop comment 'comment';\n");
  ENTER ();  
  MTStopInstance (diagram, "d", "comment", TIME, NULL);
  MTShowLastObject (diagram, false);

  
  /* ACTION */
  /* ACTION */
  printf ("Making an action:\n"
          "e: action 'ACTION action';\n");
  ENTER ();
  MTAction (diagram, "e", "Action A", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Making an action with no text:\n"
          "e: action '';\n");
  ENTER ();
  MTAction (diagram, "e", "", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Making an action with a comment:\n"
          "e: action 'ACTION ''action''' comment 'ACTION ''action''';\n");
  ENTER ();
  MTAction (diagram, "e", "ACTION 'action'", "ACTION 'action'", TIME, NULL);
  MTShowLastObject (diagram, false);
  

  /* TIMER */
  /* TIMER */ /* Starting a timer */
  printf ("Starting a timer:\n"
          "f: set Timer1, 1;\n");
  ENTER ();
  MTStartTimer (diagram, "f", "Timer1", "1", NULL, NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Starting a timer with a duration:\n"
          "g: set Timer2, 2 (5);\n");
  ENTER ();
  MTStartTimer (diagram, "g", "Timer2", "2", "10", NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Starting a timer with a duration and parameters:\n"
          "i: set Timer2, 2 (5) /* #SDTMSCPAR(4, 5, 6) */;\n");
  ENTER ();
  MTStartTimer (diagram, "i", "Timer3", "3", "11", "4, 5, 6",
                NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Starting a timer with a duration, parameters and comment:\n"
          "j: set Timer2, 2 (5) /* #SDTMSCPAR(4, 5, 6) */"
          "comment 'comment';\n");
  ENTER ();
  MTStartTimer (diagram, "j", "Timer4", "4", "12", "4, 5, 6", "comment",
                TIME, NULL);
  MTShowLastObject (diagram, false);


  /* TIMER */
  /* TIMER */ /* Stopping a timer */
  printf ("Stopping a timer:\n"
          "f: reset Timer1, 1;\n");
  ENTER ();
  MTStopTimer (diagram, "f", "Timer1", "1", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Stopping a timer with a comment:\n"
          "g: reset Timer2, 2 comment 'Timer2 Stopped';\n");
  ENTER ();
  MTStopTimer (diagram, "g", "Timer2", "2", "Timer2 Stopped", TIME, NULL);
  MTShowLastObject (diagram, false);
  

  /* TIMER */
  /* TIMER */ /* time out */
  printf ("Timeout:\n"
          "i: timeout Timer3, 3;\n");
  ENTER ();
  MTTimeout (diagram, "i", "Timer3", "3", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Timeout with a comment:\n"
          "j: timeout Timer4, 4 comment 'Timer4 Timed out';\n");
  ENTER ();
  MTTimeout (diagram, "j", "Timer4", "4", "Timer4 Timed out", TIME, NULL);
  MTShowLastObject (diagram, false);
  
  
  /* MESSAGES */
  /* MESSAGES */ /* Sending */
  printf ("Sending a message:\n"
          "i: out m1, 1 to j;\n");
  ENTER ();
  MTSendMessage (diagram, "i", "j", "m1", "1", NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Sending a message with parameters:\n"
          "i: out m2, 2, (a, b, c) to j;\n");
  ENTER ();
  MTSendMessage (diagram, "i", "j", "m2", "2", "a, b, c", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Sending a message with parameters and a comment:\n"
          "i: out m3, 3, (a, b, c) to j comment 'comment';\n");
  ENTER ();
  MTSendMessage (diagram, "i", "j", "m3", "3", "a, b, c", "comment",
                 TIME, NULL);
  MTShowLastObject (diagram, false);

  
  /* MESSAGES */
  /* MESSAGES */ /* Receiving messages */
  printf ("Receiving a message:\n"
          "j: in m1, 1 from i;\n");
  ENTER ();
  MTReceiveMessage (diagram, "i", "j", "m1", "1", NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Receiving a message with parameters:\n"
          "j: in m2, 2, (a, b, c) from i;\n");
  ENTER ();  
  MTReceiveMessage (diagram, "i", "j", "m2", "2", "a,b,c,", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Receiving a message with parameters and a comment:\n"
          "i: in m3, 3, (a, b, c) from i comment 'receiveing comment';\n");
  ENTER ();
  MTReceiveMessage (diagram, "i", "j", "m3", "3", "a, b, c",
                    "receiving comment",
                    TIME, NULL);
  MTShowLastObject (diagram, false);

  
  /* MESSAGES */
  /* MESSAGES */ /* Found messages */
  printf ("Finding a message:\n"
          "j: in f1 from found i;\n");
  ENTER ();
  MTFoundMessage (diagram, "i", "j", "f1", NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Finding a message from an unknown instance:\n"
          "j: in f1 from found;\n");
  ENTER ();
  MTFoundMessage (diagram, NULL, "j", "f1", NULL, NULL, TIME, NULL);

  printf ("Finding a message with parameters:\n"
          "j: in f2 from found i;\n");
  ENTER ();
  MTFoundMessage (diagram, "i", "j", "f2", "c, d, e", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Finding a message with parameters and comment:\n"
          "j: in f3 from found i comment 'comment';\n");
  ENTER ();
  MTFoundMessage (diagram, "i", "j", "f3", "c, d, e", "comment", TIME, NULL);
  MTShowLastObject (diagram, false);


  /* MESSAGES */
  /* MESSAGES */ /* Lost messages */
  printf ("Loosing a message:\n"
          "j: out l1 to lost i;\n");
  ENTER ();
  MTLostMessage (diagram, "i", "j", "l1", NULL, NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Loosing a message with no termination to an instance:\n"
          "j: out l1 to lost ;\n");
  ENTER ();
  MTLostMessage (diagram, "j", NULL, "l1", NULL, NULL, NULL, TIME, NULL);

  printf ("Loosing a message with parameters:\n"
          "j: out l2 to lost i;\n");
  ENTER ();
  MTLostMessage (diagram, "i", "j", "l2", NULL, "c, d, e", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);


  printf ("Loosing a message with parameters and comment:\n"
          "j: out l3 to lost i comment 'comment';\n");
  ENTER ();
  MTLostMessage (diagram, "i", "j", "l3", NULL, "c, d, e", "comment",
                 TIME, NULL);
  MTShowLastObject (diagram, false);


  /* MESSAGES */
  /* MESSAGES */ /* Transforming Sent messages to lost messages */
  printf ("Transformation of a sent message to a lost message\n");
  printf ("First, send a message:\n"
          "i: out s1, 10 to j;\n");
  ENTER ();
  MTSendMessage (diagram, "i", "j", "s1", "10", NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Then, Transform it to a lost message\n"
          "NOTE: The msgIdentifers are the same!\n"
          "j: out s1, 10 to lost i;\n");
  ENTER ();
  MTLostMessage (diagram, "i", "j", "s1", "10", NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);


  printf ("Transfromation of a sent message to a lost message\n");
  printf ("First, send a message with parameters:\n"
          "i: out s2, 11, (a, b, c) to j;\n");
  ENTER ();
  MTSendMessage (diagram, "i", "j", "s2", "11", "a, b, c", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);


  printf ("Then, Transform it to a lost message\n"
          "NOTE: The msgIdentifers are the same,\n"
          "and we don't need to supply the parameters again!\n"
          "j: out s1, 10 to lost i;\n");
  ENTER ();
  MTLostMessage (diagram, "i", "j", "s2", "11", NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  /* COREGION */
  /* COREGION */ /* Start Coregion */
  printf ("Starting a coregion:\n"
          "i: concurrent;\n");
  ENTER ();
  MTStartCoregion (diagram, "i", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Starting a coregion with a comment:\n"
          "j: concurrent comment 'comment';\n");
  ENTER ();
  MTStartCoregion (diagram, "j", "comment", TIME, NULL);
  MTShowLastObject (diagram, false);


  /* COREGION */
  /* COREGION */ /* End Coregion */
  printf ("Ending a coregion:\n"
          "i: endconcurrent;\n");
  ENTER ();
  MTEndCoregion (diagram, "i", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Ending a coregion with a comment:\n"
          "j: endconcurrent comment 'comment';\n");
  ENTER ();
  MTEndCoregion (diagram, "j", "comment", TIME, NULL);
  MTShowLastObject (diagram, false);
  


  /* CONDITION */
  /* CONDITION */ /* Simple Condition */
  printf ("Condition (not shared):\n"
          "i: condition C;\n");
  ENTER ();
  MTCondition (diagram, "i", "C", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Condition (not shared) with a comment:\n"
          "i: condition C comment 'comment';\n");
  ENTER ();
  MTCondition (diagram, "i", "C", "comment", TIME, NULL);
  MTShowLastObject (diagram, false);



  /* CONDITION */
  /* CONDITION */ /* Shared Condition */
  printf ("Condition shared with two instance axes:\n"
          "i, j: condition C;\n");
  ENTER ();
  MTCondition (diagram, "i, j", "C", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Condition shared with two instance axes and a comment:\n"
          "i, j: condition C comment 'comment';\n");
  ENTER ();
  MTCondition (diagram, "i, j", "C", "comment", TIME, NULL);
  MTShowLastObject (diagram, false);
#endif /* SEMANTICS_OK */



#ifdef IDENTIFIER_DEMO
  { 
    MTIdentifier idM1 = MTGetNewIdentifier (diagram); 
    MTIdentifier idM2 = MTGetNewIdentifier (diagram);
    MTIdentifier idM3 = MTGetNewIdentifier (diagram);

    MTIdString idString;

    int instFIFO;
    int instLIFO;

    int mSendM1;
    int mSendM2;
    int mSendM3;

    int mReceiveM1;
    int mReceiveM2;
    int mReceiveM3;

    printf ("We will send several messages of the same name between two\n"
            "instances. The messages will be identified by the\n"
            "<msgIdentifer>\n\n");
  
    /* Create our instances */
    printf ("Normal instance:\n"
            "FIFO: instance;\n");
    ENTER ();
    MTInstanceHead (diagram, "FIFO", NULL, NULL, NULL, NULL, NULL, TIME, NULL);
    MTShowLastObject (diagram, false);
    instFIFO = MTGetLastObjectId (diagram);

    printf ("Normal instance:\n"
            "LIFO: instance;\n");
    ENTER ();  
    MTInstanceHead (diagram, "LIFO", NULL, NULL, NULL, NULL, NULL, TIME, NULL);
    MTShowLastObject (diagram, false);
    instLIFO = MTGetLastObjectId (diagram);

    /* Send our messages (with the same name) */

    MTIdentifierToStr (idM1, idString);
    printf ("Sending a message (global id: idM1=%s)\n"
            "FIFO: out m, %s to LIFO;\n", idString, idString);
    ENTER ();
    MTSendMessage (diagram, "FIFO", "LIFO", "m", idString,
                   NULL, NULL, TIME, NULL);
    MTShowLastObject (diagram, false);
    mSendM1 = MTGetLastObjectId (diagram);

    MTIdentifierToStr (idM2, idString);
    printf ("Sending a message (global id: idM2=%s)\n"
            "FIFO: out m, %s to LIFO;\n", idString, idString);
    ENTER ();
    MTSendMessage (diagram, "FIFO", "LIFO", "m", idString,
                   NULL, NULL, TIME, NULL);
    MTShowLastObject (diagram, false);
    mSendM2 = MTGetLastObjectId (diagram);

    MTIdentifierToStr (idM3, idString);
    printf ("Sending a message (global id: idM3=%s)\n"
            "FIFO: out m, %s to LIFO;\n", idString, idString);
    ENTER ();
    MTSendMessage (diagram, "FIFO", "LIFO", "m", idString,
                   NULL, NULL, TIME, NULL);
    MTShowLastObject (diagram, false);
    mSendM3 = MTGetLastObjectId (diagram);


    printf ("\n"
            "Now we receive the messages in reverse order.\n");

    MTIdentifierToStr (idM3, idString);
    printf ("Receiveing a message (global id: idM3=%s)\n"
            "LIFO: in m, %s from LIFO;\n", idString, idString);
    ENTER ();
    MTReceiveMessage (diagram, "FIFO", "LIFO", "m", idString,
                      NULL, NULL, TIME, NULL);
    MTShowLastObject (diagram, false);
    mReceiveM3 = MTGetLastObjectId (diagram);

    MTIdentifierToStr (idM2, idString);
    printf ("Receiveing a message (global id: idM2=%s)\n"
            "LIFO: in m, %s from LIFO;\n", idString, idString);
    ENTER ();
    MTReceiveMessage (diagram, "FIFO", "LIFO", "m", idString,
                      NULL, NULL, TIME, NULL);
    MTShowLastObject (diagram, false);
    mReceiveM2 = MTGetLastObjectId (diagram);

    MTIdentifierToStr (idM1, idString);
    printf ("Receiveing a message (global id: idM1=%s)\n"
            "LIFO: in m, %s from LIFO;\n", idString, idString);
    ENTER ();
    MTReceiveMessage (diagram, "FIFO", "LIFO", "m", idString,
                      NULL, NULL, TIME, NULL);
    MTShowLastObject (diagram, false);
    mReceiveM1 = MTGetLastObjectId (diagram);


    printf ("\n"
            "Now make the MSC Editor/Trace window really small to observe\n"
            "the efects of showing the objects we have saved referenses to\n");

    printf ("Show instFIFO\n");
    ENTER ();
    MTShowObject (diagram, instFIFO, false);

    printf ("Show instLIFO\n");
    ENTER ();
    MTShowObject (diagram, instLIFO, false);

    printf ("Show mSendM1\n");
    ENTER ();
    MTShowObject (diagram, mSendM1, false);

    printf ("Show mSendM2\n");
    ENTER ();
    MTShowObject (diagram, mSendM2, false);

    printf ("Show mSendM3\n");
    ENTER ();
    MTShowObject (diagram, mSendM3, false);


    printf ("Show mReceiveM3\n");
    ENTER ();
    MTShowObject (diagram, mReceiveM3, false);

    printf ("Show mReceiveM1\n");
    ENTER ();
    MTShowObject (diagram, mReceiveM2, false);

    printf ("Show mReceiveM1\n");
    ENTER ();
    MTShowObject (diagram, mReceiveM1, false);
  }
#endif /* IDENTIFIER_DEMO */

  

#ifdef SEMANTICS_WRONG
  
  printf ("Section SEMANTICS_WRONG\n"
          "-----------------------\n\n");

  /* INSTANCE */
  /* Lay out some instances used for testing */
  printf ("We create some instances to test on:\n");
  
  printf ("Normal instance:\n"
          "terminated: instance;\n");
  ENTER ();
  MTInstanceHead (diagram, "terminated",
                  NULL, NULL, NULL, NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Ending an instance:\n"
          "terminated: endinstance;\n");
  ENTER ();
  MTInstanceEnd  (diagram, "terminated", NULL, TIME, NULL); 
  MTShowLastObject (diagram, false);


  printf ("Normal instance:\n"
          "aa: instance;\n");
  ENTER ();
  MTInstanceHead (diagram, "aa", NULL, NULL, NULL, NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Normal instance:\n"
          "bb: instance;\n");
  ENTER ();
  MTInstanceHead (diagram, "bb", NULL, NULL, NULL, NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Normal instance:\n"
          "cc: instance;\n");
  ENTER ();
  MTInstanceHead (diagram, "cc", NULL, NULL, NULL, NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);


  /* Adding objects to TERMINATED instances. */
  printf ("Adding Objects to TERMINATED instances.\n\n");
  
  printf ("Ending a terminated instance:\n"
          "terminated: endinstance;\n");
  ENTER ();
  MTInstanceEnd  (diagram, "terminated", NULL, TIME, NULL); 
  MTShowLastObject (diagram, false);
  
  printf ("Stopping a terminated instance:\n"
          "terminated: stop;\n");
  ENTER ();
  MTStopInstance (diagram, "terminated", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Making an action on a terminated instance:\n"
          "terminated: action 'ACTION action';\n");
  ENTER ();
  MTAction (diagram, "terminated", "Action A", "'", TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Starting a timer on a terminated instance:\n"
          "terminated: set Timer1, 1;\n");
  ENTER ();
  MTStartTimer (diagram, "terminated",
                "Timer1", "11", NULL, NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Stopping a timer on a terminated instance:\n"
          "terminated: reset TimerT, 1;\n");
  ENTER ();
  MTStopTimer (diagram, "terminated", "TimerT", "11", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Timeout on a terminated instance:\n"
          "terminated: timeout Timer3, 3;\n");
  ENTER ();
  MTTimeout (diagram, "terminated", "Timer3", "3", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  /* messages */

  printf ("Sending a message from a terminated instance:\n"
          "terminated: out bad1, 12 to aa;\n");
  ENTER ();
  MTSendMessage (diagram, "terminated", "aa",
                 "bad1", "12", NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Sending a message to a terminated instance:\n"
          "aa: out bad2, 13 to terminated;\n");
  ENTER ();
  MTSendMessage (diagram, "aa", "terminated",
                 "bad2", "13", NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  /* Adding Objects to NONEXISTENT Instances */
  printf ("Adding objects to NONEXISTENT Instances.\n\n");
  

  printf ("Adding an instance end to a non-existent instance:\n"
          "NonExistent: endinstance;\n");
  ENTER ();
  MTInstanceEnd  (diagram, "NonExistent", NULL, TIME, NULL); 
  MTShowLastObject (diagram, false);

  printf ("Adding an instance stop to a non-existent instance:\n"
          "NonExistent: stop;\n");
  ENTER ();
  MTStopInstance (diagram, "NonExistent", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Adding an action to a non-existent instance:\n"
          "NonExistent: action 'Action A';\n");
  ENTER ();
  MTAction (diagram, "NonExistent", "Action A", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Starting a timer on a non-existent instance:\n"
          "NonExistent: set Timer1, 11 (5);\n");
  ENTER ();
  MTStartTimer (diagram, "NonExistent", "Timer1", "11", "5", NULL, 
                NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Stopping a timer on a non-existent instance:\n"
          "NonExistent: reset Timer1, 11;\n");
  ENTER ();
  MTStopTimer (diagram, "NonExistent", "Timer1", "11", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Timeing out on a non-existent instance:\n"
          "NonExistent: reset Timer1, 11;\n");
  ENTER ();
  MTTimeout (diagram, "NonExistent", "Timer1", "11", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Adding a Condition on a non-existent instance:\n"
          "NonExistent: condition Cond;\n");
  ENTER ();
  MTCondition (diagram, "NonExistent", "Cond", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Create an instance from a non-existent instance:\n"
          "(Instance created, but error on the create-line).\n"
          "Created: instance;\n"
          "NonExistentCreator: create (1, 2);\n");
  ENTER ();
  MTCreateInstance (diagram, "NonExistentCreator", "1, 2", NULL, TIME, NULL, 
                    "Created", NULL, NULL, NULL, NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Starting a coregion on a non-existent instance:\n"
          "NonExistent: concurrent;\n");
  ENTER ();
  MTStartCoregion (diagram, "NonExistent", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Ending a coregion on a non-existent instance:\n"
          "NonExistent: endconcurrent;\n");
  ENTER ();
  MTEndCoregion (diagram, "NonExistent", NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Sending a message from a non-existent instance to an existing:\n"
          "NonExistent: out Mess_1, 21 to aa;\n");
  ENTER ();
  MTSendMessage (diagram, "NonExistent", "aa", "Mess_1", "21",
                 NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Sending a message from one non-existent instance to another:\n"
          "NonExistent: out Mess_1, 22 to NonExistent2;\n");
  ENTER ();
  MTSendMessage (diagram, "NonExistent", "NonExistent2", "Mess_1", "21",
                 NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Sending a message from an existing instance to a non-existing:\n"
          "aa: out Mess_1, 23 to NonExistent;\n");
  ENTER ();
  MTSendMessage (diagram, "aa", "NonExistent", "Mess_1", "23",
                 NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);
  

  printf ("Receiving a message from an existing instance to a non-existing\n"
          "NonExistent: in Mess_1, 23, from aa;\n");
  ENTER ();
  MTReceiveMessage (diagram, "aa", "NonExistent", "Mess_1", "23",
                    NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Receive a message from a non-existing instance to another\n"
          "NonExistent2 : in Mess_1, 22 from NonExistent;\n");
  ENTER ();
  MTReceiveMessage (diagram, "NonExistent", "NonExistent2", "Mess_1",
                    NULL, NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Receive a message from a non-existent instance to an existing",
          "aa: in Mess_1 from NonExistent;\n" );
  ENTER ();
  MTReceiveMessage (diagram, "Send", "Unknown", "Mess_Name",
                    NULL, NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);


  printf ("Loosing a message from a non-existing instance:\n");
  ENTER ();
  MTLostMessage (diagram, "NonExistent", NULL, "Lost_Mess",
                 NULL, NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);  

  printf ("Finding a message to a non-existing instance:\n");
  ENTER ();
  MTFoundMessage (diagram, NULL, "NonExistent", "Found_Mess",
                  NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

#endif /* SEMANTICS_WRONG */



#ifdef INTERFACE_VIOLATIONS

  printf ("Section INTERFACE_VIOLATIONS\n"
          "----------------------------\n\n");

  printf ("We create some instances to test on:\n");

  printf ("Normal instance:\n"
          "Sender: instance;\n");
  ENTER ();
  MTInstanceHead (diagram, "Sender", NULL, NULL, NULL, NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Normal instance:\n"
          "Receiver: instance;\n");
  ENTER ();
  MTInstanceHead (diagram, "Receiver",
                  NULL, NULL, NULL, NULL, NULL, TIME,NULL);
  MTShowLastObject (diagram, false);


  printf ("Condition shared with all instance axes is NOT handled\n"
          "when output is directed to the MSC Editor/Tracer:\n"
          "all: condition C comment 'comment';\n");
  ENTER ();
  MTCondition (diagram, "all", "C", "comment", TIME, NULL);
  MTShowLastObject (diagram, false);

  /* MESSAGES */
  /* MESSAGES */ /* Receiving messages with sending problems*/
  
  printf ("Send a message without specifying a message name:\n"
          "MTSendMessage (diagram, \"Send\", \"Receive\", NULL /* no mess */, "
          "NULL, NULL, NULL, TIME, NULL);\n");
  ENTER ();
  MTSendMessage (diagram, "Send", "Receive",
                 NULL, NULL, NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);

  printf ("Receive a message without having message name:\n"
          "MTReceiveMessage (diagram, \"Send\", \"Receive\", NULL /*no messs*/"
          ", NULL, NULL, NULL, TIME, NULL);\n");
  ENTER ();
  MTReceiveMessage (diagram, "Send", "Receive", NULL,
                    NULL, NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);


  printf ("MTInstanceHead function has the most complicated structure\n"
          "of optional parameters. We give one bad example here.\n"
          "Instance head with <kindDenominatorName> but without\n"
          "<kindDenominator>:\n"
          "MTInstanceHead (diagram, \"instanceName\", \"kindDenominatorName\""
          ", NULL, NULL, NULL, NULL, TIME, NULL);\n");
  ENTER ();
  MTInstanceHead (diagram, "instanceName", "kindDenominatorName", NULL,
                  NULL, NULL, NULL, TIME, NULL);
  MTShowLastObject (diagram, false);
  

#endif /* INTERFACE_VIOLATIONS */
  
  MTEndMSCDiagram (&diagram);
  MTDisconnect ();
  
  printf ("End of trace\n");
  ENTER ();
  return 0;
}



