using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

//using System.Collections;
namespace WcfTicketingService
{


    [ServiceBehavior(InstanceContextMode =
        InstanceContextMode.Single,
        ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class Ticketing : ITicketService
    {
        //---used to represent all the seats---
        //bool[,] seatsArray = new bool[10, 10];

        //---używane do blokowania---
        private object locker = new object();

        private SeatStatus _seatStatus = null;

        //---przechowuje wszystkich klientów podłączonych do usługi---
        private Dictionary<Client, ITicketCallBack> clients =
            new Dictionary<Client, ITicketCallBack>();

        public Ticketing() { }

        //---dodawanie nowego klienta do słownika---
        public void RegisterClient(Guid guid)
        {
            ITicketCallBack callback =
                OperationContext.Current.GetCallbackChannel
                <ITicketCallBack>();

            //---uniemożliwia jednoczesne dodawania kilku klientów---
            lock (locker)
            {
                clients.Add(new Client { id = guid }, callback);
            }
        }

        //---wyrejestrowanie klienta przez usunięcie jego 
        // identyfikatora ze słownika---
        public void UnRegisterClient(Guid guid)
        {
            var query = from c in clients.Keys
                        where c.id == guid
                        select c;
            clients.Remove(query.First());
        }

        //---wywoływana przez klientów przy rezerwowaniu miejsc---
        public void SetSeatStatus(string strSeats)
        {
            _seatStatus = new SeatStatus
            {
                //---zapisuje miejsca rezerwowane przez klienta---
                Seats = strSeats
            };

            //_seatStatus.CallBack =
            //    OperationContext.Current.GetCallbackChannel
            //    <WcfTicketingService.ITicketCallBack>();

            //---pobranie wszystkich klientów ze słownika---
            var query = (from c in clients
                         select c.Value).ToList();

            //---tworzenie wywołania zwrotnego---
            Action<ITicketCallBack> action =
                delegate(ITicketCallBack callback)
                {
                    //---wywołanie zwrotne przekazuje wszystkim klientom 
                    // informację o zarezerwowaniu miejsc---
                    callback.SeatStatus(_seatStatus.Seats);
                };

            //---wywołanie zwrotne uruchamiane jest dla każdego podłączonego klienta--- 
            query.ForEach(action);
        }
    }

}

public class SeatStatus
{
    //---ciąg znaków reprezentujący miejsce rezerwowane przez klienta---
    public string Seats { get; set; }
}
