// ATCDialog.cxx - Functions and classes to handle the pop-up ATC dialog
//
// Written by Alexander Kappes and David Luff, started February 2003.
//
// Copyright (C) 2003  Alexander Kappes and David Luff
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <simgear/compiler.h>

#include <simgear/structure/commands.hxx>
#include <simgear/props/props_io.hxx>

#include <Main/globals.hxx>
#include <GUI/gui.h>		// mkDialog
#include <GUI/new_gui.hxx>
#include <Main/fg_props.hxx>

#include "ATCDialogOld.hxx"
#include "ATC.hxx"
#include "ATCmgr.hxx"
#include "ATCutils.hxx"
#include <Airports/simple.hxx>
#include <ATC/CommStation.hxx>

#include <sstream>

using std::ostringstream;
using std::cerr;
using std::endl;

FGATCDialog *current_atcdialog;

// For the command manager - maybe eventually this should go in the built in command list
#if 0
static bool do_ATC_dialog(const SGPropertyNode* arg) {
        cerr << "Running ATCDCL do_ATC_dialog" << endl;
	current_atcdialog->PopupDialog();
	return(true);
}

static bool do_ATC_freq_search(const SGPropertyNode* arg) {
	current_atcdialog->FreqDialog();
	return(true);
}
#endif

ATCMenuEntry::ATCMenuEntry() {
  stationid    = "";
  //stationfr    = 0;
  transmission = "";
  menuentry    = "";
  callback_code = 0;
}

ATCMenuEntry::~ATCMenuEntry() {
}

void atcUppercase(string &s) {
	for(unsigned int i=0; i<s.size(); ++i) {
		s[i] = toupper(s[i]);
	}
}

// find child whose <name>...</name> entry matches 'name'
static SGPropertyNode *getNamedNode(SGPropertyNode *prop, const char *name) {
	SGPropertyNode* p;

	for (int i = 0; i < prop->nChildren(); i++)
		if ((p = getNamedNode(prop->getChild(i), name)))
			return p;

	if (!strcmp(prop->getStringValue("name"), name))
		return prop;

	return 0;
}


FGATCDialog::FGATCDialog() {
	_callbackPending = false;
	_callbackTimer = 0.0;
	_callbackWait = 0.0;
	_callbackPtr = NULL;
	_callbackCode = 0;
	_gui = (NewGUI *)globals->get_subsystem("gui");
}

FGATCDialog::~FGATCDialog() {
}

void FGATCDialog::Init() {
	// Add ATC-dialog to the command list
	//globals->get_commands()->addCommand("ATC-dialog", do_ATC_dialog);
	// Add ATC-freq-search to the command list
	//globals->get_commands()->addCommand("ATC-freq-search", do_ATC_freq_search);

	// initialize properties polled in Update()
	//globals->get_props()->setStringValue("/sim/atc/freq-airport", "");
	//globals->get_props()->setIntValue("/sim/atc/transmission-num", -1);
}

void FGATCDialog::Update(double dt) {
	//static SGPropertyNode_ptr airport = globals->get_props()->getNode("/sim/atc/freq-airport", true);
	//string s = airport->getStringValue();
	//if (!s.empty()) {
	//	airport->setStringValue("");
	//	FreqDisplay(s);
	//}

	//static SGPropertyNode_ptr trans_num = globals->get_props()->getNode("/sim/atc/transmission-num", true);
	//int n = trans_num->getIntValue();
	//if (n >= 0) {
	//	trans_num->setIntValue(-1);
	//	PopupCallback(n);
	//}

	//if(_callbackPending) {
	//	if(_callbackTimer > _callbackWait) {
	//		_callbackPtr->ReceiveUserCallback(_callbackCode);
	//		_callbackPtr->NotifyTransmissionFinished(fgGetString("/sim/user/callsign"));
	//		_callbackPending = false;
	//	} else {
	//		_callbackTimer += dt;
	//	}
	//}
}

// Add an entry
void FGATCDialog::add_entry(const string& station, const string& transmission, const string& menutext, atc_type type, int code) {

  ATCMenuEntry a;

  a.stationid = station;
  a.transmission = transmission;
  a.menuentry = menutext;
  a.callback_code = code;

  (available_dialog[type])[station.c_str()].push_back(a);

}

void FGATCDialog::remove_entry( const string &station, const string &trans, atc_type type ) {
  atcmentry_vec_type* p = &((available_dialog[type])[station]);
  atcmentry_vec_iterator current = p->begin();
  while(current != p->end()) {
    if(current->transmission == trans) current = p->erase(current);
	else ++current;
  }
}

void FGATCDialog::remove_entry( const string &station, int code, atc_type type ) {
  atcmentry_vec_type* p = &((available_dialog[type])[station]);
  atcmentry_vec_iterator current = p->begin();
  while(current != p->end()) {
    if(current->callback_code == code) current = p->erase(current);
	else ++current;
  }
}

// query the database whether the transmission is already registered;
bool FGATCDialog::trans_reg( const string &station, const string &trans, atc_type type ) {
  atcmentry_vec_type* p = &((available_dialog[type])[station]);
  atcmentry_vec_iterator current = p->begin();
  for ( ; current != p->end() ; ++current ) {
    if ( current->transmission == trans ) return true;
  }
  return false;
}

// query the database whether the transmission is already registered;
bool FGATCDialog::trans_reg( const string &station, int code, atc_type type ) {
  atcmentry_vec_type* p = &((available_dialog[type])[station]);
  atcmentry_vec_iterator current = p->begin();
  for ( ; current != p->end() ; ++current ) {
    if ( current->callback_code == code ) return true;
  }
  return false;
}

// Display the ATC popup dialog box with options relevant to the users current situation.
void FGATCDialog::PopupDialog() {
	const char *dialog_name = "atc-dialog";
	SGPropertyNode_ptr dlg = _gui->getDialogProperties(dialog_name);
	if (!dlg)
		return;

	_gui->closeDialog(dialog_name);

	SGPropertyNode_ptr button_group = getNamedNode(dlg, "transmission-choice");
	// remove all transmission buttons
	button_group->removeChildren("button", false);

	string label;
	FGATCMgr* pAtcMgr = globals->get_ATC_mgr();
	if (!pAtcMgr)
	{
	    SG_LOG(SG_ATC, SG_ALERT, "ERROR! No ATC manager! Oops...");
	    return;
	}
	FGATC* atcptr = pAtcMgr->GetComm1ATCPointer();	// Hardwired to comm1 at the moment

	if (!atcptr) {
		label = "Not currently tuned to any ATC service";
		mkDialog(label.c_str());
		return;
	}

	if(atcptr->GetType() == ATIS) {
		label = "Tuned to ATIS - no communication possible";
		mkDialog(label.c_str());
		return;
	}

	atcmentry_vec_type atcmlist = (available_dialog[atcptr->GetType()])[atcptr->get_ident()];
	atcmentry_vec_iterator current = atcmlist.begin();
	atcmentry_vec_iterator last = atcmlist.end();
	
	if(!atcmlist.size()) {
		label = "No transmission available";
		mkDialog(label.c_str());
		return;
	}

	const int bufsize = 32;
	char buf[bufsize];
	// loop over all entries in atcmentrylist
	for (int n = 0; n < 10; ++n) {
		snprintf(buf, bufsize, "/sim/atc/opt[%d]", n);
		fgSetBool(buf, false);

		if (current == last)
			continue;

		// add transmission button (modified copy of <button-template>)
		SGPropertyNode *entry = button_group->getNode("button", n, true);
		copyProperties(button_group->getNode("button-template", true), entry);
		entry->removeChildren("enabled", true);
		entry->setStringValue("property", buf);
		entry->setIntValue("keynum", '1' + n);
		if (n == 0)
			entry->setBoolValue("default", true);

		snprintf(buf, bufsize, "%d", n + 1);
		string legend = string(buf) + ". " + current->menuentry;
		entry->setStringValue("legend", legend.c_str());
		entry->setIntValue("binding/value", n);
		current++;
	}

	_gui->showDialog(dialog_name);
	return;
}

void FGATCDialog::PopupCallback(int num) {
    FGATCMgr* pAtcMgr = globals->get_ATC_mgr();
    if (!pAtcMgr)
    {
        SG_LOG(SG_ATC, SG_ALERT, "ERROR! No ATC manager! Oops...");
        return;
    }
	FGATC* atcptr = pAtcMgr->GetComm1ATCPointer();	// FIXME - Hardwired to comm1 at the moment

	if (!atcptr)
		return;

	if (atcptr->GetType() == TOWER) {
		//cout << "TOWER " << endl;
		//cout << "ident is " << atcptr->get_ident() << endl;
		atcmentry_vec_type atcmlist = (available_dialog[TOWER])[atcptr->get_ident()];
		int size = atcmlist.size();
		if(size && num < size) {
			//cout << "Doing callback...\n";
			ATCMenuEntry a = atcmlist[num];
			atcptr->SetFreqInUse();
			string pilot = atcptr->GenText(a.transmission, a.callback_code);
			fgSetString("/sim/messages/pilot", pilot.c_str());
			// This is the user's speech getting displayed.
			_callbackPending = true;
			_callbackTimer = 0.0;
			_callbackWait = 5.0;
			_callbackPtr = atcptr;
			_callbackCode = a.callback_code;
		} else {
			//cout << "No options available...\n";
		}
		//cout << "Donded" << endl;
	}
}



