/*
 * Client for the naming service bank example.
 */

#include "Naming/Bank/BankS.h"
#include "Naming/Bank/BankC.h"
#include "Naming/Bank/Util.h"

#include <tao/corba.h>

namespace
{
  const char* names[10] =
    {
      ACE_TEXT ("George"),
      ACE_TEXT ("Lenon"),
      ACE_TEXT ("Stephen"),
      ACE_TEXT ("Mary"),
      ACE_TEXT ("Gary"),
      ACE_TEXT ("Jonathan"),
      ACE_TEXT ("Luke"),
      ACE_TEXT ("Rachel"),
      ACE_TEXT ("Paul"),
      ACE_TEXT ("Steve")
    };
};

static void showAccount (const Bank::Account_ptr account)
{
  CORBA::String_var name = account->name ();
  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("Current Balance for Account Holder %s is: %.2f\n"),
              name.in (), account->balance ()));
}

int
main (int argc, char **argv)
{
  try
    {
      Bank::AccountManager_var accMgrVar;

      // Get the ORB reference.
      CORBA::ORB_var orbVar = CORBA::ORB_init (argc, argv);
      if (CORBA::is_nil (orbVar.in ()))
        {
          ACE_ERROR_RETURN ((LM_ERROR,
                             ACE_TEXT ("ERROR: Could not instantiate the ORB\n")),
                            1);
        }

      // Get the account manager reference.
      Util util (orbVar.in ());

      accMgrVar = util.getAccManagerObject ();
      if (CORBA::is_nil (accMgrVar.in ()))
        {
          ACE_ERROR_RETURN ((LM_ERROR,
                             ACE_TEXT ("ERROR: Could not get the account manager reference\n")),
                            1);
        }

      // Create the accounts.
      for (CORBA::ULong i = 0; i < 10; ++i)
        {
          try
            {
              accMgrVar->createAccount (names[i], 10000);
            }
          catch (const Bank::AccountManager::AlreadyExists &)
            {
              ACE_DEBUG ((LM_DEBUG,
                          ACE_TEXT ("Account for %s already exists: using the existing account information\n"),
                          names[i]));
            }
        }

      // Run the example.
      Bank::Account_var georgeAccVar =
        accMgrVar->getAccount (ACE_TEXT ("George"));
      showAccount (georgeAccVar.in ());

      georgeAccVar->deposit (21000);
      showAccount (georgeAccVar.in ());

      georgeAccVar->withdraw (9000);
      showAccount (georgeAccVar.in ());

      georgeAccVar->withdraw (3900);
      showAccount (georgeAccVar.in ());

      Bank::Account_var rachelAccVar =
        accMgrVar->getAccount (ACE_TEXT ("Rachel"));
      showAccount (rachelAccVar.in ());

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

  return 0;
}
