// Purpose.  Proxy design pattern demo (virtual proxy).
// 
// Discussion.  Oftentimes, it is desirable to defer the cost of creating
// and initializing an object until we are sure it will actually be used.
// A solution for this context is to use another object, a "proxy", to
// stand-in for the real object until the real object is called for.  If
// that happens, the proxy instantiates the real object, and thereafter
// delegates all requests to the real object.

#include <iostream.h>
#include <stdio.h>

class BaseImage {
public:
    virtual void draw() = 0;
};

class RealImage : public BaseImage {
public:
    RealImage ( char* name ) { strcpy( _name, name ); }
    void draw()              { cout << "   drawing image " << _name << endl; }
private:
   char  _name[20];
};

class Image : public BaseImage {
public:
   Image( char* name ) { strcpy( _name, name );  _image = NULL; }
   void draw()         { _getImage()->draw(); }
protected:
   RealImage* _getImage() {
      if ( ! _image) {
         cout << "   retrieving image " << _name << endl;
         _image = new RealImage( _name ); }
      return _image; }
private:
   char        _name[20];
   RealImage*  _image;
};


main()
{
   Image*  images[6];
   char    temp[20];

   for (int i=1; i < 6; i++) {
      sprintf( temp, "image%d", i );
      images[i] = new Image( temp ); }

   cout << "Exit[0], Image[1-5]: ";
   cin >> i;
   while (i)
   {
      images[i]->draw();
      cout << "Exit[0], Image[1-5]: ";
      cin >> i;
   }
}    

// Exit[0], Image[1-5]: 1
//    retrieving image image1
//    drawing image image1
// Exit[0], Image[1-5]: 1
//    drawing image image1

