//Function: check all the AVAILABLE reservations in db, and find out in the span of current time which table is reserved
        //  set certain reservations and tables involed as RESERVED
        //Remarks: be involved periodically and automaticlly by a timer
        //  this is the begining of all the state transfer of tables and reservations in memory
        //$调用存储过程,查数据库里的reservation,比对现在时间和reservation预定时间的关系,确定哪些订单进入到reserved状态了
        public static void CheckTableReserved()
        {
            DataContextDataContext dc = new DataContextDataContext();

            //装数据库返回的数据集合
            ISingleResult<get_reserved_tablename_and_reservationResult> rs = dc.get_reserved_tablename_and_reservation(DateTime.Now);
            foreach (get_reserved_tablename_and_reservationResult r in rs)
            {
                //装reservation的很多dish
                List<DishQuota> dishQuotaList = new List<DishQuota>();

                //in fact no dish, if dishes is not allowed to order before custom comming
                //ISingleResult<get_dishquota_by_reservationResult> rs2 = dc.get_dishquota_by_reservation(r.id);
                //foreach (get_dishquota_by_reservationResult r2 in rs2)
                //{
                //    double price = 0;
                //    ISingleResult<get_dish_by_nameResult> rs3 = dc.get_dish_by_name(r2.dish_name);
                //    foreach (get_dish_by_nameResult r3 in rs3)
                //    {
                //        price = (double)r3.price;
                //    }

                //    DishQuota dishQuota = new DishQuota(r2.id, r2.dish_name, price, (int)r2.quato, r2.note);
                //    dishQuotaList.Add(dishQuota);
                //}

                //从数据集的一条记录组装一个reservation
                Reservation reservation = new Reservation(
                    r.id,
                    r.user_from,
                    r.customer_name,
                    r.phone,
                    (DateTime)r.arrive_time,
                    r.table_name,
                    (int)r.seat,
                    (ReservationType)r.type,
                    (ReservationState)r.state,
                    dishQuotaList);

                foreach (SysTable t in Restaurant.tableList)
                {
                    //如果内存中的table是还没被约定的,占用的,这条reservation预定的就是这张桌子,吧这张桌子预定到这张桌子
                    if (t.name == reservation.tableName && (t.state != TableState.BUSY && t.state != TableState.TIMEOUT))
                    {
                        t.SetReservation(reservation); //reservation 绑定到桌子
                        t.ChageState(TableState.RESERVED); //桌子状态reserved
                    }
                    else
                    { }
                }
            }
        }
 public static void CommitReservation(Reservation pR)
 {
     DataContextDataContext dc = new DataContextDataContext();
     //$dc.ins
     dc.insert_reservation(
         (Guid?)pR.id,
         pR.userFrom,
         pR.customerName,
         pR.phone,
     (DateTime?)pR.arriveTime,
     pR.tableName,
     (int?)pR.seat,
     (int?)pR.state);
 }
        //没有预定的人直接用餐,提交信息
        protected void ButtonSubmit_Click(object sender, EventArgs e)
        {
            Reservation reservation = new Reservation(
                Guid.NewGuid(),
                manager.name,
                TextBoxUserName.Text,
                TextBoxPhone.Text,
                Convert.ToDateTime(LabelTime.Text),
                tableName,
                Convert.ToInt32(TextBoxSeat.Text),
                ReservationType.WalkIn,
                ReservationState.BUSY);

            manager.WalkInArrive(tableName, reservation); //转换桌子状态

            Response.Redirect(System.Configuration.ConfigurationManager.AppSettings["ManagerMain"]);  //跳转回manager主页
        }
        //new 一个 resrvation, 把页面上信息填充进来,提交resrvation
        protected void ButtonSubmit_Click(object sender, EventArgs e)
        {
            Guid id = Guid.NewGuid();
            //DateTime arriveTime = new DateTime();
            DateTime arriveTime = Convert.ToDateTime(TextBoxArriveDate.Text + " " + DropDownListTime.Text);

            Reservation reservation = new Reservation(
                id,
                customer.name,
                TextBoxUserName.Text,
                TextBoxPhone.Text,
                arriveTime,
                DropDownListTableName.SelectedItem.Text,
                Convert.ToInt32(TextBoxSeat.Text),
                ReservationType.Reservation, ReservationState.RESRVED);

            customer.CommitReservation(reservation);

            Response.Write("<Script>alert('Your reservation is recorded by system, please be on time!')</script>");
        }
        public static List<Reservation> GetAllHistoryReservation()
        {
            List<Reservation> reservationList = new List<Reservation>();

            DataContextDataContext dc = new DataContextDataContext();
            ISingleResult<select_all_history_reservationResult> rs = dc.select_all_history_reservation();
            foreach (select_all_history_reservationResult r in rs)
            {
                List<DishQuota> dishQuotaList = new List<DishQuota>();

                ISingleResult<get_dishquota_by_reservationResult> rs2 = dc.get_dishquota_by_reservation(r.id);
                foreach (get_dishquota_by_reservationResult r2 in rs2)
                {
                    double price = 0;
                    ISingleResult<get_dish_by_nameResult> rs3 = dc.get_dish_by_name(r2.dish_name);
                    foreach (get_dish_by_nameResult r3 in rs3)
                    {
                        price = (double)r3.price;
                    }

                    DishQuota dishQuota = new DishQuota(r2.id, r2.dish_name, price, (int)r2.quato, r2.note);
                    dishQuotaList.Add(dishQuota);
                }

                Reservation reservation = new Reservation(
                    r.id,
                    r.user_from,
                    r.customer_name,
                    r.phone,
                    (DateTime)r.arrive_time,
                    r.table_name,
                    (int)r.seat,
                    (ReservationType)r.type,
                    (ReservationState)r.state,
                    dishQuotaList);
                reservationList.Add(reservation);
            }

            return reservationList;
        }
        //CustomService customService = new CustomService();
        //ManagerService managerService = new ManagerService();
        //Function: assign a table to the custoemr who come into restaurant without a reservation
        //Parameters:
        //    string pTableName: table name assigned to the customer walk in
        //    Reservation pR: reservation generated which belongs to this new customer
        //Remarks:
        //    change the TableState to BUSY, the table is specified by  pTableName
        //    set the ReservationState to BUSY of pR
        //$ 一个客人进来,没有提前预定的 table 从available->busy,reservation-》busy
        public void WalkInArrive(string pTableName, Reservation pR)
        {
            foreach (SysTable t in Restaurant.tableList)
            {
                if (t.name == pTableName)
                {
                    DataContextDataContext dc = new DataContextDataContext();
                    dc.insert_reservation(
                        (Guid?)pR.id,
                        pR.userFrom,
                        pR.customerName,
                        pR.phone,
                        (DateTime?)pR.arriveTime,
                        pR.tableName,
                        (int?)pR.seat,
                        (int?)pR.state);

                    t.SetReservation(pR); //so the table now maintain a reservation
                    t.ChageState(TableState.BUSY);
                    t.GetReservation().ChangeState(ReservationState.BUSY);
                }
                else
                { }
            }
        }
        //Function: search reservations by keyword
        //Remarks: if the keyword == null, return all the records
        public List<Reservation> SearchReservationMatch(string keyword)
        {
            List<Reservation> reservationList = new List<Reservation>();

            if (keyword == null)
            { keyword = "%"; }  //search all the records
            else
            { }
            DataContextDataContext dc = new DataContextDataContext();
            ISingleResult<search_current_reservation_by_keywordResult> rs = dc.search_current_reservation_by_keyword(keyword);
            foreach (search_current_reservation_by_keywordResult r in rs)
            {
                List<DishQuota> dishQuotaList = new List<DishQuota>();

                ISingleResult<get_dishquota_by_reservationResult> rs2 = dc.get_dishquota_by_reservation(r.id);
                foreach (get_dishquota_by_reservationResult r2 in rs2)
                {
                    double price = 0;
                    ISingleResult<get_dish_by_nameResult> rs3 = dc.get_dish_by_name(r2.dish_name);
                    foreach (get_dish_by_nameResult r3 in rs3)
                    {
                        price = (double)r3.price;
                    }

                    DishQuota tDishQuota = new DishQuota(r2.id, r2.dish_name, price, (int)r2.quato, r2.note);
                    dishQuotaList.Add(tDishQuota);
                }

                Reservation reservation = new Reservation(
                    r.id,
                    r.user_from,
                    r.customer_name,
                    r.phone,
                    (DateTime)r.arrive_time,
                    r.table_name,
                    (int)r.seat,
                    (ReservationType)r.type,
                    (ReservationState)r.state,
                    dishQuotaList);
                reservationList.Add(reservation);
            }
            return reservationList;
        }
 public void ModifyReservation(Reservation pR)
 {
     PublicService.ModifyReservation(pR);
 }
 //reservation is committed when the custom finish the meal
 //reservation state is updated and dishes is added to db
 //used by manager
 //private void FinishReservationWithDish(Reservation pR)
 //{
 //    DataContextDataContext dc = new DataContextDataContext();
 //    foreach (DishQuota dq in pR.dishQuotaList)
 //    {
 //        dc.insert_reservation_dish(dq.id, pR.id, dq.dishName, dq.quota, dq.note);
 //    }
 //    pR.ChangeState(ReservationState.FINISH);
 //}
 //Function: submit a new reservation for a customer
 //    invoked when a manager helps customer reserve a meal in restaurant
 public void CommitReservation(Reservation pR)
 {
     PublicService.CommitReservation(pR);
 }
        //Function: initiate all the tables with states, by querying the db
        ////从数据库把桌子信息读出来,带着当前的状态
        public static void InitAllTable()
        {
            tableList = new List<SysTable>();

            DataContextDataContext dc = new DataContextDataContext();
            ISingleResult<select_all_tableResult> rs = dc.select_all_table();
            foreach (select_all_tableResult r in rs)
            {
                Reservation reservation = null;

                ISingleResult<get_current_reservation_by_tableResult> rs2 = dc.get_current_reservation_by_table(r.name);
                foreach (get_current_reservation_by_tableResult r2 in rs2)
                {
                    List<DishQuota> dishQuotaList = new List<DishQuota>();

                    ISingleResult<get_dishquota_by_reservationResult> rs3 = dc.get_dishquota_by_reservation(r2.id);
                    foreach (get_dishquota_by_reservationResult r3 in rs3)
                    {
                        double price = 0;
                        ISingleResult<get_dish_by_nameResult> rs4 = dc.get_dish_by_name(r3.dish_name);
                        foreach (get_dish_by_nameResult r4 in rs4)
                        {
                            price = (double)r4.price;
                        }

                        DishQuota dishQuota = new DishQuota((Guid)r3.id, r3.dish_name, price, (int)r3.quato, r3.note);
                        dishQuotaList.Add(dishQuota);
                    }

                    reservation = new Reservation(
                    r2.id,
                    r2.user_from,
                    r2.customer_name,
                    r2.phone,
                    (DateTime)r2.arrive_time,
                    r2.table_name,
                    (int)r2.seat,
                    (ReservationType)r2.type,
                    (ReservationState)r2.state,
                    dishQuotaList);
                }

                //only one reservation is bound to a table in a certain time
                //  in exact this foreach loop, not outside
                SysTable table = new SysTable(
                (Guid)r.id,
                r.name,
                (int)r.seat,
                r.pict_path,
                (TableState)r.current_state
                );
                table.SetReservation(reservation);
                tableList.Add(table);
            }
        }
 public static void ModifyReservation(Reservation pR)
 {
     DataContextDataContext dc = new DataContextDataContext();
     dc.update_reservation((Guid?)pR.id,
         pR.userFrom,
         pR.customerName,
         pR.phone,
         (DateTime?)pR.arriveTime,
         pR.tableName,
         (int?)pR.seat,
         (int?)pR.type,
         (int?)pR.state);
 }
        public static List<Reservation> GetReservationByDurationAndUser(DateTime pBeginTime, DateTime pEndTime, string pUserFrom)
        {
            List<Reservation> reservationList = new List<Reservation>();

            DataContextDataContext dc = new DataContextDataContext();
            ISingleResult<select_reservation_by_duration_and_userResult> rs = dc.select_reservation_by_duration_and_user((DateTime?)pBeginTime, (DateTime?)pEndTime, pUserFrom);
            foreach (select_reservation_by_duration_and_userResult r in rs)
            {
                List<DishQuota> dishQuotaList = new List<DishQuota>();

                ISingleResult<get_dishquota_by_reservationResult> rs2 = dc.get_dishquota_by_reservation(r.id);
                foreach (get_dishquota_by_reservationResult r2 in rs2)
                {
                    double price = 0;
                    ISingleResult<get_dish_by_nameResult> rs3 = dc.get_dish_by_name(r2.dish_name);
                    foreach (get_dish_by_nameResult r3 in rs3)
                    {
                        price = (double)r3.price;
                    }

                    DishQuota tDishQuota = new DishQuota(r2.id, r2.dish_name, price, (int)r2.quato, r2.note);
                    dishQuotaList.Add(tDishQuota);
                }

                Reservation reservation = new Reservation(
                    r.id,
                    r.user_from,
                    r.customer_name,
                    r.phone,
                    (DateTime)r.arrive_time,
                    r.table_name,
                    (int)r.seat,
                    (ReservationType)r.type,
                    (ReservationState)r.state,
                    dishQuotaList);
                reservationList.Add(reservation);
            }
            return reservationList;
        }
 public void SetReservation(Reservation pReservation)
 {
     currentReservation = pReservation;
 }