//In vxml.h
//-----------
//Prototype

event_set MenuAlgorithm( rtp_info_t* rtp,
                         DOM_Node firstMenuNode);
//In vxml.cpp
//-------------

else if( childNode.getNodeName().equals( "form" ) ||
	 childNode.getNodeName().equals( "menu" ) )
{
	/**
	 * A <form> or <menu> tag is found
  	 */
//... rest of the code
}




//In vxml.cpp
//-------------
event_set event;
if( first_found )
{
  if( firstFormNode.getNodeName().equals( "menu" ) )
  {
    TRACE("Found a menu tag");
    DOM_Node firstMenuNode = firstFormNode;
    event = MenuAlgorithm( &rtp, firstMenuNode);
    TRACE("MenuAlgorithm complete now in main");
   }
//... rest of the code

}



/**
/* Interpretation Model of a menu
 * A menu behaves like a form with a single field that does all the work.  
 * The menu prompts become field prompts.  The menu event handlers become 
 * the field event handlers.  The menu grammars become form grammars.
 * Upon entry, the menu's grammars are built and enabled, and the prompt
 * is played.  When the user input matches a choice, control transitions 
 * according to the value of the next attribute of the <choice>, only one
 * of which may be specified.
 *
 * @param rtp is the associated context.
 * 
 * @param firstMenuNode is the the menu node
 *
 * @param doc is the document node
 *
 * @return the event set indicating where to go next
 *
 */

event_set MenuAlgorithm( rtp_info_t* rtp,
                         DOM_Node firstMenuNode)
{
  bool dtmfAttribute = false;
  DOM_Node menuItem = firstMenuNode;
  vector<string> choice;
  std::string choiceContent;


  //if dtmf attribute of the menu tag is true the choices' dtmf grammars
  //are implicit
  if( menuItem.getAttributes() != NULL )
  {
     DOM_Node dtmf;
     if( ( dtmf = menuItem.getAttributes().getNamedItem( "dtmf" ) ) != NULL )
     {
        TRACE("menu has dtmf attribute");
        char* p= dtmf.getNodeValue().transcode();
        if( !strcmp(p,"true") )
          dtmfAttribute = true;
        delete[] p;
     }//if dtmf
  }//if menuItem

  event_set event;
  FIA_ResetEvent(event);
  int implicitDtmf = 0;

  //build the grammar and the transition destination 
  FOREACH( child, menuItem.getChildNodes(),{
    DOMString name = child.getNodeName();
    if( name.equals( "choice" ) ){
      if( child.getAttributes() != NULL ){
        //We only support the next attribute for this element
        
          DOM_Node next = child.getAttributes().getNamedItem( "next" );

          if( !dtmfAttribute ){     
            DOM_Node dtmf = child.getAttributes().getNamedItem( "dtmf" );
          }

          DOM_Node text = child.getAttributes().getNamedItem( "#text" );
	  if( text != NULL ){
            choiceContent += FIA_GetTextPart( text );
          }             


          if( next != NULL ){
            char* pNext = next.getNodeValue().transcode();
            
            if( pNext != NULL ){
           
              if( !dtmfAttribute && dtmf != NULL ){

                char* pDtmf = dtmf.getNodeValue().transcode();
                if( pDtmf != NULL && pNext != NULL ){            
                  int choiceNumber = atoi( pDtmf );
		choice[ choiceNumber ] = pDtmf;
                }

              delete[] pDtmf;
            
	      }//if dtmfattribute	

              else{
                choice[ implicitDtmf++ ] = pNext;
            
              }
           }//if pNext   
                 
            delete[] pNext;
       
          }//if next            
       
	else{
          TRACE("We only support next attribute for choice");
        }
      }//if choice's attributes
  
    }//if choice

  });//foreach

  std::string prompt="";
  bool enumEmpty=false;
  FOREACH( child,menuItem.getChildNodes(),{
    DOMString name = child.getNodeName();
    if( name.equals( "prompt" ) ){
      std::string v = FIA_GetPrompt( child, menuItem );
      prompt += v;
    }//prompt
    else if( name.equals( "enumerate" ) ){
      if( child.getChildNodes == NULL )
        enumEmpty = true;
    
    }//enumerate
        
  });//FOREACH	

    if( prompt != "" ){
      if( enumEmpty ){
        //Add choice contents to the prompt
        prompt += choiceContent;
      }//enumEmpty

      TTS_EnqueueText(rtp,prompt);
    }
    else{
      TRACE("No prompt for this menu");
    }

    //get user input and match them against active grammars for the menu  
   
    //user_input_t user_input;
    if( rtp != NULL ){
      //reset the current_input to ignore previously detected digits

      rtp->current_input = "";

      double timeout=0;  //in second
      struct timespec ts;

      while( true ){
        int retcode=0;
        bool queue_empty = FIA_IsSendQueueEmpty(rtp);

        struct timeval now;
        gettimeofday( &now, NULL );
        ts = timespec_delay( now, timeout );
        
        retcode = pthread_cond_timedwait(&rtp->cond_vxml, &rtp->mutex_vxml, &ts);

        TRACE("MenuAlgorithm - getting user input");

        if( rtp->oTerminateVxml ){
          TRACE("MenuAlgorithm - oTerminate is true");
          break;
        }

        TRACE("Calling IsSendQueueEmpty");
        bool queue_empty_after = FIA_IsSendQueueEmpty(rtp);        
        TRACE("Result is "<<queue_empty_after);

        if(retcode){
          if( retcode == ETIME || retcode == ETIMEDOUT ){
            if( queue_empty && queue_empty_after ){
              event.event = "noinput";
              return( event );
            }
            else{
              //some other error
              event.event = "error";
              return( event );
           }
          }//ETIME
        }//retcode
         
        //if we are here we will check the current_input
        if( rtp->current_input != "" ){ 
          std::string current_input = rtp->current_input;
          
          if( rtp->current_input[rtp->current_input.size() - 1] == '#'){
            TRACE( "Input is # terminated" );

            current_input.erase( current_input.size()-1, 1);
          }//# terminated

          if( current_input == "**" ){
            TRACE( "Help Requested" );
            event.event = "help";
            return( event );
          }//help
          else{
             char* ptr = current_input.c_str();
             int userChoice = atoi( ptr );
             if( choice[ userChoice ] != NULL ){
               TRACE( "Matched");
               event.event = "matched";
               event.goto_next = choice[ userChoice ];
               return( event );
             }//choice
          }
          else{
             event.event = "nomatch";
             return( event );
          }
        }//current_input
      }//while
   }//if rtp not null
return( event );
}//MenuAlgorithm
