// Purpose.  Chain of Responsibility.   #include <iostream.h>
//
// Discussion.  Instead of the client   class H {
// having to know about the number of   public:
// "handlers", and manually map re-        H( H* next = 0 ) {
// quests to available handlers; de-          id_   = count_++;
// sign the handlers into an "intel-          busy_ = 0;
// ligent" chain.  Clients "launch            next_ = next;
// and leave" requests with the head       }
// of the chain.                           ~H() {
                                              cout << id_<<" dtor" << endl;
#include <iostream.h>                         // don't get into a loop
                                              if (next_->next_) {
class H {                                        H* t = next_;
public:                                          next_ = 0;
   H() {                                         delete t;
      id_ = count_++;                      }  }
      busy_ = 0;                           void setNext( H* next ) {
   }                                          next_ = next;
   ~H() {                                  }
      cout << id_ << " dtor" << endl;      void handle() {
   }                                          if (busy_ = ! busy_)
   int handle() {                                cout << id_ << " handles"
      if (busy_ = ! busy_) {                        << endl;
         cout << id_ << " handles"            else {
            << endl;                             cout << id_ << " is busy"
         return 1;                                  << endl;
      } else {                                   next_->handle();
         cout << id_ << " is busy"         }  }
            << endl;                    private:
         return 0;                         int        id_, busy_;
   }  }                                    H*         next_;
private:                                   static int count_;
   int        id_, busy_;               };
   static int count_;                   int H::count_ = 1;
};
int H::count_ = 1;                      H* setUpList() {
                                           H* first = new H;
void main( void ) {                        H* last = new H(first);
   const int TOTAL = 2;                    first->setNext( last );
   H* list[TOTAL] = { new H, new H };      return first;
                                        }
   for (int i=0; i < 6; i++)
      for (int j=0; 1 ;                 void main( void ) {
               j = (j + 1) % TOTAL)        H* head = setUpList();
         if (list[j]->handle())
            break;                         for (int i=0; i < 6; i++)
                                              head->handle();
   for (int k=0; k < TOTAL; k++)
      delete list[k];                      delete head;
}                                       }

// 1 handles                            // 1 handles
// 1 is busy                            // 1 is busy
// 2 handles                            // 2 handles
// 1 handles                            // 1 handles
// 1 is busy                            // 1 is busy
// 2 is busy                            // 2 is busy
// 1 handles                            // 1 handles
// 1 is busy                            // 1 is busy
// 2 handles                            // 2 handles
// 1 handles                            // 1 handles
// 1 dtor                               // 1 dtor
// 2 dtor                               // 2 dtor




// Purpose.  Chain of Responsibility design pattern

// 1. Put a "next" pointer in the base class
// 2. The "chain" method in the base class always delegates to the next object
// 3. If the derived classes cannot handle, they delegate to the base class

#include <iostream>
#include <vector>
#include <ctime>
using namespace std;

class Base {
   Base* next;                // 1. "next" pointer in the base class
public:
   Base() { next = 0; }
   void setNext( Base* n ) { next = n; }
   void add( Base* n ) { if (next) next->add( n ); else next = n; }
   // 2. The "chain" method in the base class always delegates to the next obj
   virtual void handle( int i ) { next->handle( i ); }
};

class Handler1 : public Base { public:
   /*virtual*/ void handle( int i ) {
      if (rand() % 3) {       // 3. Don't handle requests 3 times out of 4
         cout << "H1 passsed " << i << "  ";
         Base::handle( i );   // 3. Delegate to the base class
      } else
         cout << "H1 handled " << i << "  ";
}  };

class Handler2 : public Base { public:
   /*virtual*/ void handle( int i ) {
      if (rand() % 3) { cout << "H2 passsed " << i << "  "; Base::handle( i ); }
      else cout << "H2 handled " << i << "  ";
}  };

class Handler3 : public Base { public:
   /*virtual*/ void handle( int i ) {
      if (rand() % 3) { cout << "H3 passsed " << i << "  "; Base::handle( i ); }
      else cout << "H3 handled " << i << "  ";
}  };

void main( void ) {
   srand( time( 0 ) );
   Handler1 root;   Handler2 two;   Handler3 thr;
   root.add( &two );   root.add( &thr );
   thr.setNext( &root );
   for (int i=1; i < 10; i++) {
      root.handle( i );   cout << '\n';
}  }

// H1 passsed 1  H2 passsed 1  H3 passsed 1  H1 passsed 1  H2 handled 1
// H1 handled 2
// H1 handled 3
// H1 passsed 4  H2 passsed 4  H3 handled 4
// H1 passsed 5  H2 handled 5
// H1 passsed 6  H2 passsed 6  H3 passsed 6  H1 handled 6
// H1 passsed 7  H2 passsed 7  H3 passsed 7  H1 passsed 7  H2 handled 7
// H1 handled 8
// H1 passsed 9  H2 passsed 9  H3 handled 9




// Purpose.  Chain of Responsibility and Composite

// 1. Put a "next" pointer in the base class
// 2. The "chain" method in the base class always delegates to the next object
// 3. If the derived classes cannot handle, they delegate to the base class

#include <iostream>
#include <vector>
#include <ctime>
using namespace std;

class Component {
   int        value;
   Component* next;             // 1. "next" pointer in the base class
public:
   Component( int v, Component* n ) { value = v;  next = n; }
   void setNext( Component* n )     { next = n; }
   virtual void traverse()          { cout << value << ' '; }
   // 2. The "chain" method in the base class always delegates to the next obj
   virtual void volunteer()         { next->volunteer(); }
};

class Primitive : public Component { public:
   Primitive( int val, Component* n = 0 ) : Component( val, n ) { }
   /*virtual*/ void volunteer() {
      Component::traverse();
      // 3. Primitive objects don't handle volunteer requests 5 times out of 6
      if (rand() * 100 % 6 != 0)
         // 3. Delegate to the base class
         Component::volunteer();
}  };

class Composite : public Component {
   vector<Component*> children;
public:
   Composite( int val, Component* n = 0 ) : Component( val, n ) { }
   void add( Component* c ) { children.push_back( c ); }
   /*virtual*/ void traverse() {
      Component::traverse();
      for (int i=0; i < children.size(); i++)
         children[i]->traverse();
   }
   // 3. Composite objects never handle volunteer requests
   /*virtual*/ void volunteer() { Component::volunteer(); }
};

void main( void ) {
   srand( time( 0 ) );                             // 1
   Primitive seven( 7 );                           // |
   Primitive six( 6, &seven );                     // +-- 2
   Composite three( 3, &six );                     // |   |
   three.add( &six );  three.add( &seven );        // |   +-- 4 5
   Primitive five( 5, &three );                    // |
   Primitive four( 4, &five );                     // +-- 3
   Composite two( 2, &four );                      // |   |
   two.add( &four );   two.add( &five );           // |   +-- 6 7
   Composite one( 1, &two );                       // |
   Primitive nine( 9, &one );                      // +-- 8 9
   Primitive eight( 8, &nine );
   one.add( &two );  one.add( &three );  one.add( &eight );  one.add( &nine );
   seven.setNext( &eight );
   cout << "traverse: ";   one.traverse();   cout << '\n';
   for (int i=0; i < 8; i++) {
      one.volunteer();  cout << '\n';
}  }

// traverse: 1 2 4 5 3 6 7 8 9
// 4
// 4 5 6 7
// 4 5 6 7 8 9 4 5 6 7 8 9 4
// 4
// 4 5 6
// 4 5
// 4 5
// 4 5 6 7 8 9 4 5 6 7 8 9 4 5 6




// Purpose.  Chain of Responsibility - links bid on job, chain assigns job
//
// 1. Base class maintains a "next" pointer
// 2. Each "link" does its part to handle (and/or pass on) the request
// 3. Client "launches and leaves" each request with the chain
// 4. The current bid and bidder are maintained in chain static members
// 5. The last link in the chain assigns the job to the low bidder

#include <iostream>
#include <ctime>
using namespace std;

class Link {
   int   id;
   Link* next;                       // 1. "next" pointer
   static int   theBid;              // 4. Current bid and bidder
   static Link* bidder;
public:
   Link( int num ) { id = num;  next = 0; }
   void addLast( Link* l ) {
      if (next) next->addLast( l );  // 2. Handle and/or pass on
      else      next = l;
   }
   void bid() {
      int num = rand() % 9;
      cout << id << '-' << num << "  ";
      if (num < theBid) {
         theBid = num;               // 4. Current bid and bidder
         bidder = this;
      }
      if (next) next->bid();         // 2. Handle and/or pass on
      else      bidder->execute();   // 5. The last 1 assigns the job
   }
   void execute() {
      cout << id << " is executing\n";
      theBid = 999;
}  };
int   Link::theBid = 999;            // 4. Current bid and bidder
Link* Link::bidder = 0;

void main( void ) {
   Link chain( 1 );
   for (int i=2; i < 7; i++)
      chain.addLast( new Link( i ) );
   srand( time( 0 ) );
   for (i=0; i < 10; i++)
      chain.bid();                   // 3. Client "launches & leaves"
}

// 1-1  2-6  3-0  4-3  5-1  6-0  3 is executing
// 1-1  2-1  3-1  4-0  5-7  6-1  4 is executing
// 1-0  2-1  3-0  4-6  5-1  6-2  1 is executing
// 1-6  2-3  3-8  4-0  5-1  6-4  4 is executing
// 1-8  2-0  3-5  4-8  5-4  6-2  2 is executing
// 1-1  2-0  3-8  4-8  5-7  6-0  2 is executing
// 1-1  2-1  3-3  4-1  5-6  6-2  1 is executing
// 1-2  2-1  3-0  4-3  5-6  6-8  3 is executing
// 1-7  2-5  3-4  4-2  5-1  6-2  5 is executing
// 1-3  2-6  3-7  4-7  5-6  6-0  6 is executing