// Purpose.  Facade                     #include <iostream.h>
//                                      #include <string.h>
// Discussion.  Class Compute models    #define sl strlen
// a decimal digit adder module.  An
// entire "subsystem" can be configur-  class Compute {
// ed by linking as many of these       public:
// modules as the desired precision        char add( char a, char b, int& c ) {
// requires.  The "subsystem" being           int result = a + b + c - 96;
// modeled in main() is complex and           c = 0;
// burdensome to use.  Wrapping this          if (result > 9) {
// subsystem inside of a Facade that             result -= 10;
// exports a simple interface is                 c = 1;
// desirable.                                 }
                                              return result + 48;
#include <iostream.h>                      }
#include <string.h>                     };
#define sl strlen
                                        class Facade {
class Compute {                         public:
public:                                 char* add( char* a, char* b ) {
   char add( char a, char b, int& c) {     int cary = 0, i = 0;
      int result = a + b + c - 96;         char c, d;
      c = 0;                               if ((sl(a) > 1) && (sl(b) > 1)) {
      if (result > 9) {                       c = ones.add( a[1], b[1], cary );
         result -= 10;                        d = tens.add( a[0], b[0], cary );
         c = 1;                            } else if (sl(a) > 1) {
      }                                       c = ones.add( a[1], b[0], cary );
      return result + 48;                     d = tens.add( a[0],  '0', cary );
   }                                       } else if (sl(b) > 1) {
};                                            c = ones.add( b[1], a[0], cary );
                                              d = tens.add( b[0],  '0', cary );
void main( void ) {                        } else {
   Compute  tens, ones;                       c = tens.add( a[0], b[0], cary );
   char     a[9], b[9], c, d;                 d = 'x';
   int      cary;                          }
while (1) {                                if (cary) ans[i++] = '1';
   cout << "Enter 2 nums: ";               if (d != 'x') ans[i++] =  d;
   cin >> a >> b;                          ans[i++] = c;
   cout << "   sum is ";                   ans[i] = '\0';
   cary = 0;                               return ans;
   if ((sl(a) > 1) && (sl(b) > 1)) {    }
      c = ones.add( a[1], b[1], cary);  private:
      d = tens.add( a[0], b[0], cary);     Compute  tens, ones;
   } else if (sl(a) > 1) {                 char     ans[9];
      c = ones.add( a[1], b[0], cary);  };
      d = tens.add( a[0],  '0', cary);
   } else if (sl(b) > 1) {              void main( void ) {
      c = ones.add( b[1], a[0], cary);     Facade  f;
      d = tens.add( b[0],  '0', cary);     char    a[9], b[9];
   } else {                                while (1) {
      c = tens.add( a[0], b[0], cary);        cout << "Enter 2 nums: ";
      d = 'x';                                cin >> a >> b;
   }                                          cout <<"   sum is "<< f.add(a,b)
   if (cary) cout << '1';                        << endl;
   if (d != 'x') cout << d;             }  }
   cout << c << endl;
}  }                                    // Enter 2 nums: 9 13
                                        //    sum is 22
// Enter 2 nums: 99 99                  // Enter 2 nums: 19 8
//    sum is 198                        //    sum is 27
// Enter 2 nums: 38 83                  // Enter 2 nums: 3 99
//    sum is 121                        //    sum is 102
// Enter 2 nums: 5 6
//    sum is 11



// Purpose.  Facade design pattern demo.
// 
// Discussion.  Structuring a system into subsystems helps reduce
// complexity.  A common design goal is to minimize the communication and
// dependencies between subsystems.  One way to achieve this goal is to
// introduce a "facade" object that provides a single, simplified
// interface to the many, potentially complex, individual interfaces
// within the subsystem.  In this example, the "subsystem" for responding
// to a networking service request has been modeled, and a facade
// (FacilitiesFacade) interposed.  The facade "hides" the twisted and
// bizarre choreography necessary to satisfy even the most basic of
// requests.  All the user of the facade object has to do is make one or
// two phone calls a week for 5 months, and a completed service request
// results.

#include <iostream.h>

class MisDepartment {
public:
	void submitNetworkRequest() { _state = 0; }
	bool checkOnStatus() {
		_state++;
		if (_state == Complete)
			return 1;
		return 0; }
private:
	enum States {Received, DenyAllKnowledge, ReferClientToFacilities,
		FacilitiesHasNotSentPaperwork, ElectricianIsNotDone,
		ElectricianDidItWrong, DispatchTechnician, SignedOff, DoesNotWork,
		FixElectriciansWiring, Complete};
	int _state;
};

class ElectricianUnion {
public:
	void submitNetworkRequest() { _state = 0; }
	bool checkOnStatus() {
		_state++;
		if (_state == Complete)
			return 1;
		return 0; }
private:
	enum States {Received, RejectTheForm, SizeTheJob, SmokeAndJokeBreak,
		WaitForAuthorization, DoTheWrongJob, BlameTheEngineer, WaitToPunchOut,
		DoHalfAJob, ComplainToEngineer, GetClarification, CompleteTheJob,
		TurnInThePaperwork, Complete};
	int _state;
};

class FacilitiesDepartment {
public:
	void submitNetworkRequest() { _state = 0; }
	bool checkOnStatus() {
		_state++;
		if (_state == Complete)
			return 1;
		return 0; }
private:
	enum States {Received, AssignToEngineer, EngineerResearches,
		RequestIsNotPossible, EngineerLeavesCompany, AssignToNewEngineer,
		NewEngineerResearches, ReassignEngineer, EngineerReturns,
		EngineerResearchesAgain, EngineerFillsOutPaperWork, Complete};
	int _state;
};

class FacilitiesFacade {
public:
	FacilitiesFacade()          { _count = 0; }
	void submitNetworkRequest() { _state = 0; }
	bool checkOnStatus() {
		_count++;
		/* Job request has just been received */
		if (_state == Received) {
			_state++;
			/* Forward the job request to the engineer */
			_engineer.submitNetworkRequest();
			cout << "submitted to Facilities - " << _count
				<< " phone calls so far" << endl; }
		else if (_state == SubmitToEngineer) {
			/* If engineer is complete, forward to electrician */
			if (_engineer.checkOnStatus()) {
				_state++;
				_electrician.submitNetworkRequest();
				cout << "submitted to Electrician - " << _count
					<< " phone calls so far" << endl; } }
		else if (_state == SubmitToElectrician) {
			/* If electrician is complete, forward to technician */
			if (_electrician.checkOnStatus()) {
				_state++;
				_technician.submitNetworkRequest();
				cout << "submitted to MIS - " << _count
					<< " phone calls so far" << endl; } }
		else if (_state == SubmitToTechnician) {
			/* If technician is complete, job is done */
			if (_technician.checkOnStatus())
				return 1; }
		/* The job is not entirely complete */
		return 0; }
	int getNumberOfCalls() { return _count; }
private:
	enum States {Received, SubmitToEngineer, SubmitToElectrician,
		SubmitToTechnician};
	int                   _state;
	int                   _count;
	FacilitiesDepartment  _engineer;
	ElectricianUnion      _electrician;
	MisDepartment         _technician;
};

void main() {
	FacilitiesFacade  facilities;

	facilities.submitNetworkRequest();
	/* Keep checking until job is complete */
	while ( ! facilities.checkOnStatus())
		;
	cout << "job completed after only " << facilities.getNumberOfCalls()
		<< " phone calls" << endl;
}

// submitted to Facilities - 1 phone calls so far
// submitted to Electrician - 12 phone calls so far
// submitted to MIS - 25 phone calls so far
// job completed after only 35 phone calls
