#include <CosTradingC.h>

#include "Trading/Mortgage/Mortgage.h"

#include <tao/corba.h>
#include <tao/PortableServer/PortableServer.h>

int
main (int argc, char** argv)
{
  try
    {
      // Initialise the ORB.
      CORBA::ORB_var orbVar = CORBA::ORB_init (argc, argv);

      CORBA::Object_var objVar;
      CosTrading::Lookup_var lookupVar;

      // Resolve to the trading service.
      objVar = orbVar->resolve_initial_references (ACE_TEXT ("TradingService"));
      lookupVar = CosTrading::Lookup::_narrow (objVar.in ());

      // Set up parameters for query.
      CosTrading::PolicySeq policies;
      CosTrading::Lookup::SpecifiedProps desiredProps;
      CosTrading::OfferSeq_var offersVar;
      CosTrading::PolicyNameSeq_var policiesAppliedVar;
      CosTrading::OfferIterator_var iteratorVar;
      CosTrading::PropertyNameSeq propertySeq;
      char str[] = ACE_TEXT ("rate > 0.039");

      propertySeq.length (1);
      propertySeq[0] = CORBA::string_dup (ACE_TEXT ("financial_organisation"));
      desiredProps.prop_names (propertySeq);

      // Execute the query.
      lookupVar->query (ACE_TEXT ("IDL:Mortgage:1.0"),
                        str,
                        ACE_TEXT (""),
                        policies,
                        desiredProps,
                        4,
                        offersVar.out (),
                        iteratorVar.out (),
                        policiesAppliedVar.out ());

      // Display the offers.
      Mortgage_var mortgageVar;
      ACE_DEBUG ((LM_DEBUG,
                  ACE_TEXT ("%i available banks with %s\n"),
                  offersVar->length (), str));

      for (CORBA::ULong count = 0; count < offersVar->length (); ++count)
        {
          const char *value = 0;

          if ((*offersVar)[count].properties[0].value >>= value)
            {
              ACE_DEBUG ((LM_DEBUG,
                          ACE_TEXT ("Financial organisation name: %s\n"),
                          value));
            }
          else
            {
              ACE_DEBUG ((LM_DEBUG,
                          ACE_TEXT ("WARNING: Could not determine ")
                          ACE_TEXT ("financial organisation name\n")));
            }

          //Get object reference, narrow to the correct type and invoke the operation.
          mortgageVar = Mortgage::_narrow ((*offersVar)[count].reference.in ());
          ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Calculating Mortgage payments\n")));
          mortgageVar->calculateMortgage (100000, 25);
        }

      // Complete.
      orbVar->destroy ();
    }
  catch (const CORBA::Exception &ex)
    {
      ex._tao_print_exception (ACE_TEXT ("ERROR: Exception in MortgageClient.cpp:"));
      return 1;
    }

  return 0;
}
