context: using System;
  using System.Collections.Generic;
    
    // Bridge Pattern Example 
    // Extending SpaceBook with a second implementation via a Portal
    
    // Abstraction  
    class Portal  {
      Bridge bridge;
      public Portal (Bridge aSpaceBook) {
        bridge = aSpaceBook;
      }
      public void Add(string message)
         {bridge.Add(message);}
      public void Add(string friend, string message)
         {bridge.Add(friend,message);}
      public void Poke(string who)
         {bridge.Poke(who);}
    }
    
    //Bridge
    interface Bridge {
      void Add(string message);
      void Add(string friend, string message);
      void Poke(string who);
    }
    
    class SpaceBookSystem {  
    
      // The Subject
      private class SpaceBook {
        static SortedList <string,SpaceBook> community = 
            new  SortedList <string,SpaceBook> (100);
        string pages;
        string name;
        string gap = "\n\t\t\t\t";
      
        static public bool IsUnique (string name) {
          return community.ContainsKey(name);
        }
      
        internal SpaceBook (string n) {
          name = n;
          community [n] = this;
        }
      
        internal string Add(string s) {
          pages += gap+s;
          return gap+"======== "+name+"'s SpaceBook ========="+
                    pages+"\n"+
                  gap+"================================";
        }
      
        internal string Add(string friend, string message) {
           return community[friend].Add(message);
          }
        
        internal void Poke (string who, string friend) {
          community[who].pages += gap + friend + " poked you";
        }
      }
  
    
      // The Proxy (CANNOT CHANGE)
      public class MySpaceBook {
        // Combination of a virtual and authentication proxy
        SpaceBook mySpaceBook;
        string password;
        string name;
        bool loggedIn = false;
        
        void Register () {
          Console.WriteLine("Let's register you for SpaceBook");
          do { 
            Console.WriteLine("All SpaceBook names must be unique");
            Console.Write("Type in a user name: ");
              name = Console.ReadLine();
          } while (SpaceBook.IsUnique(name));
          Console.Write("Type in a password: ");
          password = Console.ReadLine();
          Console.WriteLine("Thanks for registering with SpaceBook");
        }
    
        bool Authenticate () {
          Console.Write("Welcome "+name+". Please type in your password: ");
          string supplied = Console.ReadLine();
          if (supplied==password)  {
            loggedIn = true;
              Console.WriteLine( "Logged into SpaceBook");
            if (mySpaceBook == null)
              mySpaceBook = new SpaceBook(name);
            return true;
          } 
          Console.WriteLine("Incorrect password");
          return false;
        }
      
        public void Add(string message) {
          Check();
          if (loggedIn) mySpaceBook.Add(message);
        }
      
        public void Add(string friend, string message) {
          Check();
          if (loggedIn) 
            Console.WriteLine(mySpaceBook.Add(friend, name + " said: "+message));
        }
      
        public void Poke(string who) {
          Check();
          if (loggedIn)
            mySpaceBook.Poke(who,name);
        }
      
        void Check() {
          if (!loggedIn) {
            if (password==null)
               Register();
              if (mySpaceBook == null)
               Authenticate();
          }
        } 
      }
    
      // A Proxy with little to do
      // Illustrates an alternative implementation in the Bridge pattern
      public class MyOpenBook : Bridge {
        // Combination of a virtual and authentication proxy
        SpaceBook myOpenBook;
        string name;
        static int users;
        
        public MyOpenBook (string n) {
          name = n;
          users++;
          myOpenBook = new SpaceBook(name+"-"+users);
        }
        
        public void Add(string message) {
           Console.WriteLine(myOpenBook.Add(message));
        }
        
        public void Add(string friend, string message) {
          Console.WriteLine(myOpenBook.Add(friend, name + " : "+message));
        }
        
        public void Poke(string who) {
          myOpenBook.Poke(who,name);
        }
      }
    } // end class SpaceBookSystem
  
    static class OpenBookExtensions {
      public static void SuperPoke (this Portal me, string who, string what) {
        me.Add(who, what+" you");
      }
    }
    
    // The Client
    class BridgePattern : SpaceBookSystem {
      static void Main () {
         Portal me = new Portal(new MyOpenBook("Judith"));
         me.Add("Hello world");
         me.Add("Today I worked 18 hours");
        
         Portal tom = new Portal(new MyOpenBook("Tom"));
         tom.Poke("Judith-1");
         tom.SuperPoke("Judith-1","hugged");
         tom.Add("Judith-1","Poor you");
         tom.Add("Hey, I'm on OpenBook - it was so easy!");
          //Added Console.Readkey to stop Console Window from closing.
         Console.ReadKey();
      }
    }
  /* Output
  Let's register you for SpaceBook
  All SpaceBook names must be unique
  Type in a user name: Judith
  Type in a password: yey
  Thanks for registering with SpaceBook
  Welcome Judith. Please type in your password: yey
  Logged into SpaceBook
  
          ======== Judith's SpaceBook =========
          Hello world
          Today I worked 18 hours
          Tom poked you
          Tom : hugged you
  
          ================================
  
          ======== Judith's SpaceBook =========
          Hello world
          Today I worked 18 hours
          Tom poked you
          Tom : hugged you
          Tom : Poor you
  
          ================================
  
  
gt:         ======== Tom-1's SpaceBook =========