var model = null;

$(function () {

    model = new context();
    if (model.Authorize()) {
        model.MasalistesiGetir();
        model.AppUserModelifescyle();

        model.GetAppConfig();
    }
    model.IsLoading(false);
    ko.applyBindings(model, document.getElementById("menu"));
    // login modal default ayarlar
    // örneğin: sayfanın herhangi bir yerine tıklanınca kapanmasın kapanacaksa kontrolümüz altında kapansın
    $('#loginModal').modal({ backdrop: 'static', keyboard: false, show: false })
})

window.addEventListener('scroll', function (e) {
    model.ActionScroll(window.scrollY);
});

var context = function() {

    var t = this;

    t.GetAppConfig = function () {
        if (window.localStorage && window.localStorage.getItem("menuConfig")) {
            var config = JSON.parse(window.localStorage.getItem("menuConfig"));
            Object.keys(config).map(function (item) {
                t.AppConfig[item] = config[item];
            });
        } else {
            PostQuery("/api/GetAppConfig", null, function (res) {
                if (res.Error) {
                    MessageBox(res.Error || "");
                } else {
                    t.AppConfig = res;
                    if (window.localStorage) {
                        window.localStorage.setItem("menuConfig", JSON.stringify(res));
                    }
                }
            });
        }
    }

    t.AppScrollY = ko.observable(0);

    t.CanViewByScroll = ko.observable(true);
    
    t.ActionScroll = function (currentPosition) {
        if (t.SelectedMode() !== modes.user)
            return;

        var minLimit = 50,
            isDown = currentPosition && currentPosition > t.AppScrollY();
        // scroll down
        if (isDown) {
            var limitOver = currentPosition - t.AppScrollY() > minLimit;
            if (limitOver) {
                if (t.CanViewByScroll()) {
                    t.CanViewByScroll(false);
                }
                t.AppScrollY(currentPosition);
            }            
            return;
        }
        // scroll up
        else {
            t.CanViewByScroll(true);
            t.AppScrollY(currentPosition);
            return;
        }
    }

    // sayfa yüklenirken ve ajax istekleri sırasında beklenirken kullanıcıya loading gif i gösterilmesi için kullanılır.
    t.IsLoading = ko.observable(true);

    // seçilen ana kategorinin seçilmiş elemanı ve o elemanın altındaki ürünler,
    // ör; içecekler,items:[cola,fanta]
    t.SelectedMenuItem = ko.observable();

    t.AppUserModelifescyle = function () {
        if (t.SelectedMode() == modes.user) {
            var masano = window.localStorage.getItem("masano");
            var buMasaHalaKullaniliyormu = masano ? t.MasaListesi().filter(function (f) { return f.MASANO == masano }).length > 0 : false;
            if (buMasaHalaKullaniliyormu) {
                t.Load();
                t.Navigation(screens.group_screen);
                t.SelectedMasa(masano);
                t.DepNo(undefined);
                t.Password(undefined);
                return;
            } else {
                t.Navigation(screens.masalar_screen);
            }            
            return;
        } else {
            var rn = model.LoginInfo.RoleName();
            switch (rn) {
                case RoleName.SEF:
                    t.SelectedMode(modes.admin);
                    t.Navigation(screens.appmode_screen);
                    return;
                case RoleName.GARSON:
                    t.SelectedMode(modes.garson);
                    t.Navigation(screens.masalar_screen);
                    return;
                case RoleName.KASIYER:
                    t.SelectedMode(modes.kasiyer);
                    t.Navigation(screens.masalar_screen);
                    return;
                case RoleName.MUTFAK:
                    t.SelectedMode(modes.mutfak);
                    t.Navigation(screens.masalar_screen);
                    return;
                case RoleName.USER:
                    t.SelectedMode(modes.user);
                    t.Navigation(screens.masalar_screen);
                    return;
                default:
            }
            
            return;
        }
    }

    t.AllDepartments = ko.observableArray([]);

    t.LoginDepartments = ko.pureComputed(function () {
        if (t.AllDepartments().length > 0) {
            return;
        } else {
            t.IsLoading(true);
            PostQuery("/api/GetDepartments", null, function (res) {
                if (res && res.Error) {
                    t.IsLoading(false)
                    MessageBox(res.Error, "MPOS_Departman_MasaListesi prosedürü eksik veya prosedürden dönen sonuç boş!");
                    return;
                } else {
                    if (res && res.list && res.list.obj && res.list.obj.DEPARTMANLAR && res.list.obj.DEPARTMANLAR.DEPARTMAN) {

                        t.AllDepartments(res.list.obj.DEPARTMANLAR.DEPARTMAN || []);
                    }
                    t.IsLoading(false);
                }
            })
        }
    });






    t.SortKey = ko.observable();

    t.SortType = ko.observable('asc');

    t.ChangeSort = function (key) {
        t.SortKey(key);
        t.SortType() == 'asc' ? t.SortType('desc') : t.SortType('asc');
    }

    t.MenuQuery = ko.observable();

    t.ProductGroup = ko.observable();

    t.SelectedAction = ko.observable();

    t.ComputedSelectedAction = ko.pureComputed(function () {
        var model = '';
        if (t.SelectedAction()) {
            model = t.SelectedAction();
            return model;
        } else {
            return model;
        }
    })

    t.SelectedActionButton = function (param) {
        t.Load();
        t.EditableObejct(new EditViewModel());
        t.EditableObejct().Action = param;
        t.SelectedAction(param);
    }

    t.ComputedProductGroup = ko.pureComputed(function () {
        var model = { GADI: "", GKODU: "", items: [] };
        if (t.ProductGroup()) {
            var value = t.ProductGroup();
            model.items = value.STOKLAR && value.STOKLAR.STOK || [];
            model.GADI = value.GADI;
            model.GKODU = value.GKODU;
            return model;
        } else {
            return model;
        }
    })

    t.SelectedProduct = ko.observable();

    t.SelectedProduct.subscribe(function (value) {
        if (value) {
            if (t.SelectedAction() == actions.add) {
                t.EditableObejct(new EditViewModel());
            } else if (t.SelectedAction() == actions.edit) {
                t.EditableObejct(new EditViewModel(value));
            } else {
                MessageBox("Lütfen yapacağınız işlemi seçiniz");
                return;
            }
            return;
        } else {
            return;
        }
    });
    // ek özellik 'olsun'
    t.plusExtra = function (data,parent) {
        if (data && data.Name()) {
            data.isOk(true);
            data.ExtraCount(1);
            parent.SelectedSingleProduct().TotalExtraPrice(parent.SelectedSingleProduct().TotalExtraPrice() + parseFloat(data.Price()));
        }
    }
    //ek özellik 'olmasın'
    t.minusExtra = function (data) {
        if (data && data.Name()) {
            data.isOk(false);
            data.ExtraCount(-1);
        }
    }
    //ek özellik ekleme
    t.AfterAdd = function (data) {
        if (data && data.Query()) {
            t.AddExtra(data);
        }
    }
    //ek özellik eğer databaseden gelmiyorsa sil
    t.RemoveAfterExtra = function (parent, data, index) {
        if (data.AfterAdd()) {
            parent.Extras.splice(index, 1);
            return;
        }
        if (!data.AfterAdd()) {
            data.ExtraCount("");
            data.isOk("");
            MessageBox("Bu özellik sonradan eklenmiş bir özellik olmadığından listeden silinemez", "danger");
            return
        }
        else {
            data.ExtraCount(-1);
            return;
        }
    }
    //Yeni ekstra ekleme
    t.AddExtra = function (data) {

        if (data && data.Query()) {
            var ID = data.Extras().length;
            var model = { AfterAdd: ko.observable(true), Name: ko.observable(data.Query()), DisplayName: ko.observable(data.Query()), Price: ko.observable(0), ExtraCount: ko.observable(1), isOk: ko.observable(true), ID: ko.observable(ID + 1) };
            data.Extras.push(model);
            if (data.TotalExtraPrice && data.TotalExtraPrice())
            data.TotalExtraPrice(data.TotalExtraPrice() ? data.TotalExtraPrice() : 0);
            data.TotalExtraPrice = ko.observable(0);
            data.Query(undefined);
        }
    }
    //bir ürüne ait ekstraların fiyatlarını toplayıp döndürüyor
    t.ExtrasPrice = function (data) {
        var extrasprice = 0;
        data.forEach(function (item) {
            if (item.isOk) {
                extrasprice += ((parseFloat(item.Price || 0)) * item.ExtraCount);
            }
        })
        return extrasprice;
    }

    t.SearchBox = function () {
        switch (t.Navigation()) {
            case screens.group_screen:
                return SearchBoxModel(true, t.MenuQuery,"Kategoriye göre arayın", function () { t.MenuQuery(undefined);});
            case screens.menu_screen:
                return SearchBoxModel(true, t.Query, t.SelectedMenuItem().GADI.toLowerCase() + " listesinde arayın...", function () { t.Query(undefined); });
            default:
                return SearchBoxModel(false, null,"", function () { return null });
        }
    };

    // görünecek olan sayfanın set edildiği obejct
    t.Navigation = ko.observable(screens.appmode_screen);

    // generic bottom navigasyon
    // case gövdeleri bottomNavigationSettings js de
    t.BottomNavigation = function () {
        var items= [];
        switch (t.Navigation()) {
            case screens.masalar_screen:
                items = MasalarBottomNavigation(t);
                break;
            case screens.transfer_screen:
                items = TransferBottomNavigation(t);
                break;
            case screens.cart_screen:
                items = CartBottomNavigation(t);
                break;
            case screens.detail_screen:
                items = DetailBottomNavigation(t);
                break;
            case screens.edit_screen:
                items = EditBottomNavigation(t);
                break;
            case screens.adisyon_screen:
                items = AdisyonBottomNavigation(t);
                break;
            case screens.group_screen:
                items = GroupBottomNavigation(t);
                break;
            case screens.admin_screen:
                items = AdminBottomNavigation(t);
                break;
            default:
                items = []
                break;
        }
        return { items: items };
    };

    var beginTime = { minute : "", hour : "" };
    var finishTime = { minute: "", hour: "" };

    t.BeginAndFinishTime = function () {
        var d = new Date();
            beginTime = {
                minute: d.getMinutes(),
                hour: d.getHours(),
            }
            finishTime = {
                minute: (beginTime.minute == 59 ? 0: beginTime.minute+1),
                hour: (beginTime.minute == 59 ? beginTime.hour + 1 : beginTime.hour)
            }
    }
    t.TimeControl = function () {
        if (beginTime.hour == "") {
            t.BeginAndFinishTime();
            return true;
        } else {
            d = new Date();
            if ((finishTime.hour == d.getHours() || finishTime.hour < d.getHours()) && (finishTime.minute == d.getMinutes() || finishTime.minute < d.getMinutes())) {
                t.BeginAndFinishTime();
                return true;
            }
            else
                return false;
        }           
            
    }

    t.CallGarson = function (msg) {
        if (t.TimeControl()) {
            var message = msg ? msg : t.SelectedMasa() + " nolu masadan sipariş için garson çağrıldı!";
            var data = {
                masaNo: t.SelectedMasa(),
                message: message
            };
            PostQuery("api/CallGarson", { "masaNo": data.masaNo, "message": data.message }, function (res) {
                if (res) {
                    MessageBox(res);
                }
            });
        }
        else {
            MessageBox("Talebiniz alınmıştır, en kısa sürede size yardımcı olacağız");
        }       
    }
    //t.FromToTable = {
    //    from: "",
    //    to: ""
    //}
    t.FromTable = ko.observable();
    t.ToTable = ko.observable();
    t.TransferType = ko.observable();

    t.transfer = function () {
        t.FromTable = t.SelectedMasa();
        var table = t.MasaListesi().filter(function (f) { return f.MASANO == t.FromTable });
        if (table && table[0] && table[0].DOLU()) {
            t.Navigation(screens.transfer_screen);
            t.SelectedMasa('');
            t.TableFilter(filters.bos);
            t.TransferType = "Transfer";
        }
        else
            MessageBox("Lütfen Dolu Masa Seçiniz.")
        
    }


    t.transferComplate = function () {
        if (t.SelectedMasa() == '' || t.SelectedMasa() == null)
            MessageBox("Lütfen Masa Seçiniz.")
        else {
            t.ToTable = t.SelectedMasa();
            ShowConfirm(
                (t.FromTable + ' numaralı masayı ' + t.ToTable + ' numaralı masaya transfer etmek üzeresiniz emin misiniz?'),
                function () {

                    to = model.ToTable;
                    from = model.FromTable;
                    if (from && to) {
                        var m = { 'From': from, 'To': to, 'DepNo': model.DepNo(), 'YeniMasaDepKodu': model.DepNo() };
                        PostQuery('/api/transfer', m, function (res) {
                            if (res.Error) {
                                MessageBox(res.Error || 'Transfer yapılırken hata oluştu', 'danger');
                            } else {
                                var fiscounter;
                                model.MasaListesi().forEach(function (f) {
                                    if (f.MASANO == from) {
                                        fiscounter = f.FISCOUTER();
                                        f.DOLU(false);
                                        f.FISCOUTER(undefined);
                                    }
                                    if (f.MASANO == to) {
                                        f.DOLU(true);
                                        f.FISCOUTER(fiscounter);
                                    }
                                    });
                                MessageBox('Transfer başarı ile tamamlandı');
                                model.SelectedMasa('');
                                model.Navigation(screens.masalar_screen);
                                model.TableFilter(filters.tumu);
                                model.FromTable = undefined;
                                model.ToTable = undefined;
                            }
                        });
                    }
                    else {

                    }
                   
                }
            );
            

        }
    }

    t.combine = function () {
        t.FromTable = t.SelectedMasa();
        var table = t.MasaListesi().filter(function (f) { return f.MASANO == t.FromTable });
        if (table && table[0] && table[0].DOLU()) {
            t.Navigation(screens.transfer_screen);
            t.SelectedMasa('');
            t.TableFilter(filters.dolu);
            t.TransferType = "Combine";
        }
        else
            MessageBox("Lütfen Dolu Masa Seçiniz.")

    }

    t.combineComplate = function () {
        if (t.SelectedMasa() == '' || t.SelectedMasa() == null)
            MessageBox("Lütfen Masa Seçiniz.")
        else {
            t.ToTable = t.SelectedMasa();
            if (t.ToTable != t.FromTable) {
                ShowConfirm(
                    (t.FromTable + ' numaralı masayı ' + t.ToTable + ' numaralı masa ile birleştirmek üzeresiniz emin misiniz?'),
                    function () {

                        to = model.ToTable;
                        from = model.FromTable;
                        if (from && to && (from != to)) {
                            var m = { 'From': from, 'To': to, 'DepNo': model.DepNo() };
                            PostQuery('/api/BulkTransfer', m, function (res) {
                                if (res.Error) {
                                    MessageBox(res.Error || 'Birleştirme yapılırken hata oluştu', 'danger');
                                } else {
                                    var fiscounter;
                                    var masa = model.MasaListesi().forEach(function (f) {
                                        if (f.MASANO == from) {
                                            fiscounter = f.FISCOUTER();
                                            f.DOLU(false);
                                            f.FISCOUTER(undefined);
                                        }
                                    });
                                    MessageBox('Birleştirme başarı ile tamamlandı');
                                    model.SelectedMasa('');
                                    model.Navigation(screens.masalar_screen);
                                    model.TableFilter(filters.tumu);
                                    model.FromTable = undefined;
                                    model.ToTable = undefined;
                                }
                            });
                        }
                        else {
                            MessageBox('Farklı masa seçmelisiniz.');
                        }

                    }
                );
            }
            else {
                MessageBox('Farklı masa seçiniz.')
            }
            


        }
    }

    t.LoadBefore = function () {
        if (t.masaControl()) {
            t.Load();
            if (t.List().length > 0) {
                t.Navigation(screens.group_screen);
                return;
            }
            return;
        }
         
    }

    //buradaki kod bottomnavigationsetting.js ye taşındı

    t.AdisyonGetir = function () {
        if (t.masaControl()) {
            var data = JSON.stringify({ "IsViewOrClose": "view", "DepartmentId": t.LoginInfo.DepartNo(), "DeskNo": t.SelectedMasa(), "PaymentInfo": [] });
            PostQuery("/api/ViewOrClose", { "data": data }, function (res) {
                if (res && Array.isArray(res.view)) {
                    if (res.view.length == 0) {
                        MessageBox(t.SelectedMasa() + messages.adisyonbulunamadi);
                        return
                    } else {
                        t.AdisyonSettings(res.view);
                        return
                    }
                }
            });
        }
    }

    t.AdisyonSettings = function (data) {
        var list = GroupBy(data, "AccNo");        
        list.forEach(function (item) {
            item.Odenen = ko.observable(0);
            item.selected = false;
            item.list = Array.isArray(item.list) ? item.list : [item.list];
            item.TotalPrice = ko.observable(0);
            item.DisplayText = item.key != "0" ? "Kişi No" + item.key : "";
            item.list.forEach(function (li) {
                li.CalculatedPrice = li.Price * li.Quantity;
                item.TotalPrice(item.TotalPrice() + li.CalculatedPrice);
                li.DisplayText = ko.observable(li.Price + "x" + li.Quantity + "=" + li.CalculatedPrice.toFixed(0));
                li.selected = false;
                li.TransferTo = ko.observable();
                li.TransferQuantity = "0";
                item.Odenen(parseFloat(li.Odenen));
            });
            item.TotalPrice().toFixed(1);
            item.DisplayTotalPrice = "Toplam=" + item.TotalPrice() + (item.Odenen() > 0 ? "Ödenen = " + item.Odenen() : "");
            item.AvailPrice = ko.pureComputed(function () {
                return parseFloat(item.TotalPrice()) - parseFloat(item.Odenen());
            });
            item.LastRowInfo = ko.pureComputed(function () {
                return 'Toplam=' + item.TotalPrice().toFixed(1) + (item.Odenen() > 0 ? ' | Ödenen=' + item.Odenen().toFixed(1) : '') + (item.AvailPrice() < item.TotalPrice() ? ' | Kalan=' + item.AvailPrice().toFixed(1) : '')
            })
        });
        //
        t.AdisyonListesi(ko.mapping.fromJS(list)());
        t.Navigation(screens.adisyon_screen);
        t.GetPaymentTypes();
    }

    t.AdisyonListesi = ko.observableArray([]);

    t.AdisyonKapat = function (paymentType) {
        if (paymentType != "Parçalı Ödeme") {
            var price = 0;// t.AdisyonListesi().length > 0 ? t.AdisyonListesi()[0].TotalPrice - t.AdisyonListesi() : "0";
            t.AdisyonListesi().forEach(function (item) {
              price += item.TotalPrice() - parseFloat(item.Odenen());
            })
            
            var PaymentInfo = [{ Price: 0, SubType: paymentType, Type: paymentType }];
            var data = JSON.stringify({ "IsViewOrClose": "close", "DepartmentId": t.LoginInfo.DepartNo(), "DeskNo": t.SelectedMasa(), "PaymentInfo": PaymentInfo });
            PostQuery("/api/ViewOrClose", { "data": data }, function (res) {
                if (res.Error) {
                    MessageBox(res.Error)
                } else {
                    MessageBox(res.Message);
                    t.MasaListesi().forEach(function (item) {
                        if (item.MASANO == t.SelectedMasa()) {
                            item.DOLU(false);
                            item.FISCOUTER(null);
                        }
                    });
                    t.AdisyonListesi([]);
                    t.Navigation(screens.masalar_screen);
                    t.SelectedMasa(undefined);
                }
            });
        } else {
            t.OpenPaymentForm();
        }
    }

    // ödeme alınması için açılmak istenen popup öncesi kontrol
    t.CompareAdisyonAndPayment = function (canEqual) {
        var currentAdisyonPrice = t.AdistonTotalPrice();
        var lastAmount = t.MultiPaymentTotal();
        if (canEqual)
            return currentAdisyonPrice >= lastAmount;
        else
            return currentAdisyonPrice > lastAmount;
    }
    // alınabilecek ödeme fiyatını döndürür
    t.AvailPrice = function () {
        return parseFloat(t.AdistonTotalPrice()) - parseFloat(t.AdisyonToplamOdenen());
    }

    // ödeme alınmaya müsait mi girilen rakam validayondan geçiyor mu?
    t.isAvailToPayment = function () {
        var ap = parseFloat(t.AdistonTotalPrice());
        var mp = parseFloat(t.MultiPaymentTotal());
        if (mp > 0 && mp <= ap) {
            var availPrice = t.AvailPrice();
            if (mp <= availPrice) {
                return true;
            } else {
                MessageBox("En fazla " + availPrice + " tl kadar ödeme alabilirsiniz");
                return false;
            }
        }
        else {
            if (mp > 0) {
                MessageBox("Alınmak istenen tutar adisyon tutarından büyük olamaz");
                return;
            }
            return false;
        }
    }

    // adisyon için ödeme alınması
    t.AddPayment = function () {
        if (t.isAvailToPayment()) {
            var types = ko.toJS(t.PaymentModel()).filter(function (f) {
                delete f.Items;
                delete f.Types;
                if (f.Type != undefined) {
                    f.SubType = f.Type.Name;
                    f.Type = f.Type.Type;
                }
                return f.Type != undefined && f.Price > 0;
            });
            if (types.length > 0) {
                var model = {
                    paymentListModel: JSON.stringify(types),
                    depno: t.LoginInfo.DepartNo(),
                    masaNo: t.SelectedMasa()
                };
                PostQuery("/api/AddPayment", model , function (res) {
                    if (res.Error) {
                        MessageBox(res.Error);
                    } else {
                        var errors = res.logs.filter(function (f) { return f.Error != null });
                        if (errors.length > 0)
                            t.DrawErrors(res.logs);
                        else
                            MessageBox("işlem başarı ile gerçekleştirildi.");
                        var odenen = t.AdisyonListesi()[0].Odenen(),
                            current = 0;
                        types.forEach(function (item) {
                            current += parseFloat(item.Price);
                        });
                        t.AdisyonListesi()[0].Odenen(current + odenen);
                        if (t.AdisyonListesi()[0].Odenen() == t.AdisyonListesi()[0].TotalPrice()) {
                            ShowConfirm("Tahsil edilen tutar ile adisyon tutarı eşit masa kapatılsın mı ?", function () {
                                model.AdisyonKapat('Kredi Karti');
                            });
                        }
                    }
                    t.closePaymentForm();
                    return;
                });
            }
        }
    }

    // adisyon için alınan ödemelerde eğer sunucuda bir veya birden fazla hata var ise bunu çizer.
    t.DrawErrors = function (errors) {
        var message = "";
        errors.forEach(function (item) {
            message += item.Error + "<br/>";
        });
        if (message)
            MessageBox(message);
    }

    t.OpenPaymentForm = function () {
        if (t.CompareAdisyonAndPayment(false)) {
            jQuery("#paymentForm").modal("show");
            t.AddNewPayment();
            return;
        }
        else {
            MessageBox("Bu adisyonun daha önce adisyon tutarı kadar ödemesi alınmış");
            return;
        }
    }

    t.AddNewPayment = function () {
        var price = t.PaymentModel().length == 0 ? t.AvailPrice() : 0;
        var options = t.PaymentTypes().filter(function (f) { return f.key !== "Parçalı Ödeme" });
        t.PaymentModel.push(paymentModel(options, price, null));
    }

    // adisyonun toplam fiyatını döndürür.
    t.AdistonTotalPrice = function () {
        var price = 0;
        t.AdisyonListesi().forEach(function (f) { price += parseFloat(f.TotalPrice()) });
        return price;
    }

    t.AdisyonToplamOdenen = function () {
        var price = 0;
        t.AdisyonListesi().forEach(function (itm) {
            if (itm.Odenen()) {
                price += parseFloat(itm.Odenen());
            }
        })
        return price;
    }


    t.closePaymentForm = function () {
        t.PaymentModel([]);
        jQuery("#paymentForm").modal("hide");
    }

    t.PaymentModel = ko.observableArray([]);

    // Ödeme alınması esnasında girilen tüm ödeme tiplerinin fiyat bilgisini döndürür.
    t.MultiPaymentTotal = ko.pureComputed(function () {
        var price = 0;
        t.PaymentModel().forEach(function (item) {
            if (item.Price()) {
                price += parseFloat(item.Price());
            }
        })
        return price;
    });

    // screens.detail_screen den sepete eklenmek isteniyorsa
    t.AddToBasketFromDetail = function () {
        return productModel(ko.toJS(t.SelectedSingleProduct()))
    }

    // Generic header
    // case gövdeleri topNavigationSettings.js de
    t.TopNavigation = function () {
        switch (t.Navigation()) {
            case screens.masalar_screen:
                return MasalarHeader(t);
            case screens.transfer_screen:
                return TransferHeader(t);
            case screens.group_screen:
                return HomeHeader(t);
            case screens.menu_screen:
                return MenuItemsTopNavigation(t);
            case screens.detail_screen:
                return DetailTopNavigation(t);
            case screens.edit_screen:
                return DetailTopNavigation(t);
            case screens.cart_screen:
                return CartTopNavigation(t);
            case screens.finish_screen:
                return FinishTopNavigation(t);
            case screens.appmode_screen:
                return AppModeTopNavigation(t);
            case screens.adisyon_screen:
                return AdisyonTopNavigation(t);
            case screens.admin_screen:
                return AdminTopNavigation(t);
            default:
                return t.DefaultTopNavigation();
        }
    };

    t.transferBackButton = function () {
        t.Navigation(screens.masalar_screen);
        t.TableFilter(filters.tumu);
    }

    t.CartInfo = function () {
        return "(" + (t.CartItems().length || 0) + ")";
    }

    // db den veya localdata dan gelen listenin işlenip ön tarafta kullanılması için tanımlanan array
    t.List = ko.observableArray([]);

    // searchbox da arama yapmak için kullanılacak olan object
    t.Query = ko.observable();

    // apiden bütün ürünleri getirmek için tetiklenen ilk fonksiyon
    // localstorage da data varmı varsa db ye gitme
    // db veya localstorage daki datayı işlemesi için mapping fonksiyonuna gönder
    // herhangi bir hata durumunda logla
    t.Load = function () {
        var localData = JSON.parse(window.localStorage.getItem("AllData"));
        if (localData) {
            t.DataMapping(localData);
            return;
        } else {
            PostQuery("/api/GetAll", { DepNo: t.LoginInfo.DepartNo() }, function (res) {
                if (res && res.obj && res.obj.GRUPLAR) {
                    var data = Array.isArray(res.obj.GRUPLAR.GRUP) ? res.obj.GRUPLAR.GRUP : [res.obj.GRUPLAR.GRUP];
                    t.DataMapping(data);
                } else {
                    console.log("MPOS_URUNLIST prosedürü eksik veya bu prosedürü içeriğini oluşturacak fieldlar yok önce database bu prosedürü çalıştırınız");
                    t.List([]);
                    t.IsLoading(false);
                }
            });
        }
    }

    // gelen data objesini belli kurallara göre işle ör departmanına göre valid veya invalid olarak işaretle
    // gelen objelerin içinde dönerken array olması beklenen nesneleri kotrol et array değilse array yap
    t.DataMapping = function (data) {
            var dp = t.user && t.user() && t.user() && t.user().DepartNo && t.user().DepartNo();
            data.map(function (f, index) {
                f.STOKLAR = f.STOKLAR || { STOK: [] };
                f.STOKLAR.STOK = f.STOKLAR.STOK || [];
                if (!Array.isArray(f.STOKLAR.STOK)) {
                    f.STOKLAR.STOK = [f.STOKLAR.STOK];
                }
                f.valid = ko.observable(true);
                var sayac = 0;
                f.STOKLAR.STOK.map(function(ff, index) {
                    ff.valid = ko.observable(true);
                    var counter = 0;
                    ff.FIYATLAR = ff.FIYATLAR || {};
                    // departman boşsa mevcut departmanda satılabilir
                    ff.FIYATLAR.FIYAT = ff.FIYATLAR.FIYAT || [{ DEP: dp, F: "-1" }];
                    if (!Array.isArray(ff.FIYATLAR.FIYAT)) {
                        ff.FIYATLAR.FIYAT = [ff.FIYATLAR.FIYAT];
                    }
                    ff.EKSTRALAR = ff.EKSTRALAR || {},
                        ff.EKSTRALAR.EKSTRA = ff.EKSTRALAR.EKSTRA || [];
                    if (!Array.isArray(ff.EKSTRALAR.EKSTRA)) {
                        ff.EKSTRALAR.EKSTRA = [ff.EKSTRALAR.EKSTRA];
                    }
                    ff.Extras = ff.EKSTRALAR.EKSTRA;
                    ff.Extras.map(function (Ex, idx) {
                        Ex.ExtraCount = 0;
                        Ex.ExtraCount = "";
                        Ex.Price = Ex.OFYT;
                        Ex.Name = Ex.ADI;
                        Ex.isOk = "";
                        Ex.AfterAdd = false;
                        Ex.ID = idx + 1;
                        Ex.DisplayName = (Ex.ADI) + (Ex.OFYT ? (' (' + Ex.OFYT + 'TL)') : '');
                        ff.TotalExtraPrice += (Ex.isOk == true ? parseFloat(Ex.OFYT) : 0);
                    })
                    ff.FIYATLAR.FIYAT.map(function (fff) {
                        if (fff.DEP == dp && fff.F > "-1") {
                            f.STOKLAR.STOK[index].F = fff.F;
                        }
                        if (fff.DEP != dp) {
                            counter++;
                        }
                    });
                    if (counter == ff.FIYATLAR.FIYAT.length) {
                        ff.valid(false);
                        sayac++;
                    }
                    ff.Query = "";
                    ff.AccNo = 0,
                        ff.Collapse = false;
                    ff.Quantity = ko.observable(1);
                    ff.DisplayPrice = ko.pureComputed(function () {
                        return (ff.Quantity() * (parseFloat(ff.F) + (ff.TotalExtraPrice ? parseFloat(ff.TotalExtraPrice) : 0)));
                    });
                    ff.Calori = ff.KAL || '0';
                    ff.Details = {
                        Calori: ff.Calori || 0,
                        Description: ff.DES,
                        Name: ff.SADI || "",
                        CookingTime: ff.PSURE || "",
                        Interval: ff.SSURE || "",
                        Heat: ff.SSCK || "",
                        ImgPath: ff.SR || "/Upload/empty_img.png",
                        ShowCase: ff.VR || 0,
                    };
                })
                if (sayac == f.STOKLAR.STOK.length) {
                    f.valid(false);
                }
                var images = [];
                var otherImages = [];
                f.STOKLAR.STOK.forEach(function (stok) {
                    if (stok.VR == "1") {
                        images.push(stok.SR); 
                    } else {
                        if (stok.SR) {
                            otherImages.push(stok.SR); 
                        }
                    }
                });
                f.DisplayImg = (images.length > 0 ? images[0] : (otherImages.length > 0 ? otherImages[0] : '/Upload/empty_img.png'));
            });
            data.map(function (f, idx) {
                if (f.STOKLAR.STOK.length == 0) {
                    console.log(f.GADI + " grubunda herhangi stok olmadığından listede yer almayacak bu grubun listede yer almasını istiyorsanız stok ekleyin");
                    data.splice(idx, 1);
                }
            });
            t.List(data.filter(function (f) { return f.valid() == true }));
            if (t.List().length > 0) {
                //app.LocalStorage.Write("AllData", t.List());
                window.localStorage.setItem("AllData", JSON.stringify(t.List()))
                HideLoader();
                t.IsLoading(false);
            }
    }

    t.SearchableList = ko.pureComputed(function () {
        var q = t.MenuQuery() && t.MenuQuery().toLowerCase() || undefined;
        if (q) {
            return t.List().filter(function (f) { return f.GADI.toLowerCase().indexOf(q) > -1 })
        } else {
            return t.List();
        }
        
    })

    // sayfa (navigation == home) home ise,
    // ana kategori örkeğin içecekler seçilmiş ise alt ürünlerinin bir objeye (SelectedMenuItem) set edilmesi
    t.PushItem = function (data, event) {        
        data.STOKLAR.STOK.map(function (f) {
            f.collapse = ko.observable(false);
        });
        t.SelectedMenuItem(data);
        t.Navigation(screens.menu_screen);
        scrollUp();
        t.MenuQuery(undefined);
    }

    t.MenuItems = ko.pureComputed(function () {
        if (t.SelectedMenuItem()) {
            var list = t.SelectedMenuItem().STOKLAR.STOK;
            var q = t.Query() && t.Query().toUpperCase();
            if (q) {
                return list.filter(function (f) { return f.SADI.toUpperCase().indexOf(q) > -1 });
            } else {
                return list;
            }
        } else {
            return [];
        }        
    })

    // login olmaya zorlanacak mı yoksa login olmuş ve onaylanmış ise (açılan popup da bilgileri girip karşılaştırmaya tabi olup başarılı olmuş ise),
    // durumlara göre menu yü mü yoksa login olması için popup mu çıkacağına karar verilen yer
    t.IsOpenLoginModal = function () {
        t.Password(undefined);
        t.DepNo(undefined);
        t.loginError.showAllMessages(false);
        switch (t.SelectedMode()) {
            case modes.user:
                t.AppMenuItems(false);
                $("#loginModal").modal();
                break;
            default:
                t.AppMenuItems(!t.AppMenuItems());
                t.Password(undefined);
                t.DepNo(undefined);
                t.loginError.showAllMessages(false);
                t.SelectedMasa(undefined);
                break;            
        }
    }

    // kullanıcı tarafından modal kapatılırsa bu fonksiyon çalışır
    // Password ,DepNo > nullanmalı çünkü tekrar açıldığında hafızada kalırsa kullnıcı login olabilir bu durumda güvenlik açığı olur.
    t.SetDefaultModalOptions = function () {
        $("#loginModal").modal("hide");
        t.Password(undefined);
        t.DepNo(undefined);
        t.ErrorMessage(undefined);
        t.loginError.showAllMessages(false);
    }

    // ön tarafta loginModalın kapatılması için tetiklenen ilk fonksiyon
    t.CloseLoginModal = function () {
        t.SetDefaultModalOptions();
    }

    // navbardaki menu itemlerinin görünüp görünmeyeceğinin belirlendiği object
    t.AppMenuItems = ko.observable(false);

    // baskete bir ürünü atmak için tetiklenen fonksiyon eğer baskette bu üründen varsa ürünün adedini arttırır.
    t.AddToBasket = function (data,event) {
        data.collapse && data.collapse(false);
        t.BasketAnimation(event);
        $(".product-line").map(function (i) { $($(".product-line")[i]).removeClass("unSelectedItem") })

        if (t.CartItems().length == 0) {            
            t.CartItems.push(new basketModel(data));
            return;
        }
        else {
            var currentItem = t.CartItems().filter(function (f) { return f.SID() == data.SID && t.ExtrasKey(f) == t.ExtrasKey(data) && f.AccNo() == data.AccNo });
            if (currentItem.length == 0) {
                t.CartItems.push(new basketModel(data));
            } else {
                currentItem = currentItem[0];
                currentItem.Extras().map(function (item) {
                    var count = parseInt(item.ExtraCount);
                    item.ExtraCount = count + 1;
                })
                var q = currentItem.Quantity();
                currentItem.Quantity(q + 1);

            }
        }
    }
    t.ExtrasKey = function (data) {
        return JSON.stringify(ko.toJS(data.Extras));
    };
    // sepet array objesi, AddToBasket fonksiyonun tetiklendiğinde bu objeye item i push eder.
    t.CartItems = ko.observableArray([]);

    // görünen view' in (navigasyon) sepet olması için tetiklenen fonksiyon. Eğer sepet boş ise sepet sayfası açılmaz 
    t.OpenCart = function () {
        if (t.CartItems().length == 0) {
            MessageBox("Sepetinizde ürün yok, lütfen önce ürün ekleyiniz. :)");
            return;
        }
        else {
            scrollUp();
            t.Navigation(screens.cart_screen);
            t.SelectedMenuItem(undefined);
        }
    }

    // seçilen masanın atandığı object
    t.SelectedMasa = ko.observable();

    // masa seçimi için tetiklenen fonksiyon
    t.SelectMasa = function (data) {
        t.SelectedMasa() == data.MASANO ? t.SelectedMasa(undefined) : t.SelectedMasa(data.MASANO);
        if (t.SelectedMode() == modes.user) {
            t.Load();
            t.Navigation(screens.group_screen);  
            if (window.localStorage) {
                window.localStorage.setItem("masano", data.MASANO);
            }
        }
    }

    t.FilteredTables = ko.pureComputed(function () {
        var list = t.MasaListesi();
        if (t.Navigation() == screens.masalar_screen) {
           t.SelectedMasa(undefined);
        }
        switch (t.TableFilter()) {
            case filters.bos:
                return list.filter(function (f) { return f.DOLU() !== true; });
                break;
            case filters.dolu:
                return list.filter(function (f) { return f.DOLU() === true; });
                break;
            case filters.yeni:
                return [];
                break;
            default:
                return list;
                break;
        }
    })

    // sepetteki itemların fiyatlarının toplamının hesaplandığı computed(hesaplanmış) object;
    t.CartTotalPrice = ko.pureComputed(function () {
        if (t.CartItems().length > 0) {
            var price = 0;
            t.CartItems().map(function (f) {
                price += ((parseFloat(f.F()) * f.Quantity()) + t.ExtrasPrice(f.Extras()));
            });
            return price.toFixed(2);
        }
        else {
            return "0";
        }
    })

    // sayfa eğer sepet ise (navigasyon == screens.cart_screen) sayfanın başlığının bu objectten gelen sonuç olarak HeaderTitle objesinin içerisinde çağırılır.
    t.CartTitleText = ko.pureComputed(function () {
        var adet = t.TotalCartCount() > 1 ? t.TotalCartCount() + " ADET " : "";
        return t.CartItems().length + " ÜRÜN " + adet;
    })
    
    // görünüm değişirken genellikle yapılan işlemler.
    t.DefaultNavigationChanges = function (newView,from) {
        t.Navigation(newView || screens.group_screen);
        // sadece detaydan geliniyorsa silme
        t.SelectedMenuItem(from == undefined ? undefined : t.SelectedMenuItem());
        t.Query(undefined);
        scrollUp();
    }

    t.SelectedSingleProduct = ko.observable();

    t.SetSingleProduct = function (data) {
        var koData = ko.mapping.fromJS(data);
        t.SelectedSingleProduct(koData);
        t.Navigation(screens.detail_screen);
    }   

    // sayfa sepet ise (navigaston == screens.cart_screen ) bütün ürünleri silmek için tetiklenir. 
    t.RemoveAllCart = function () {
        ShowConfirm("Sepetteki bütün ürünleri silmek istediğinize emin misiniz?", function () { model.CartItems([]); model.Navigation(screens.group_screen) });
    }

    // eğer sepette bir eleman yoksa ve (navigaston == screens.cart_screen ) sağ tarafta bulunan iconun tepesindeki sepet sayısının görünüp görünmeyeceğinin belirlendiği object
    t.CartCountvisible = ko.pureComputed(function () {
        switch (t.Navigation()) {
            case screens.cart_screen:
                return false;
            default:
                return t.CartItems().length > 0;
        }
    })

    // screens.menu_screen ve screens.cart_screen 
    t.Up = function (data) {
        data.Quantity(data.Quantity() +1);
    }
    // screens.menu_screen ve screens.cart_screen.
    t.Down = function (data, index) {
        if (data.Quantity() > 1) {
            data.Quantity(data.Quantity() - 1);
            return;
        } else {
            if (t.Navigation() == screens.cart_screen) {
                t.CartItems.splice(index, 1);
                if (t.CartItems().length == 0) {
                    t.Navigation(screens.group_screen);
                }
            }
        }
    }

    // sepetteki itemlerin her birinin adetini bulmak için kullanılır.
    t.TotalCartCount = ko.pureComputed(function () {
        if (t.CartItems().length == 0) {
            return "0";
        } else {
            var count = 0;
            t.CartItems().map(function (f) {
                count += f.Quantity();
            })
            return count;
        }
    })

    // mutfağa isteğin gitmesi için tetiklenen ilk fonksiyon
    t.Finish = function () {
        if (!t.IsLoading()) {
            t.IsLoading(true);           
            // api ye istek atılacak olan yer
            t.AddOrder();
        }                  
    }

    t.OrderComplate = function () {
        var msg = t.SelectedMasa() + " nolu masanın siparişi hazır";
        t.CallGarson(msg);
    }

    // mutfağa siparişlerin gönderilmek için kullanılan asıl fonksiyon
    t.AddOrder = function () {
        var login = ko.toJS(t.LoginInfo);
        var cart = ko.toJS(t.CartItems())
        if (cart.length > 0 && login && login.ID) {
            ///api/AddOrder bu parametreleri beklediğinden
            cart.map(function (item) {
                item.ID = item.SID;
                item.Price = item.F;
            });
            var model = {
                User: login.UserName,
                DepartmentNo: login.DepartNo,
                UserId: login.ID,
                DeskNo: t.SelectedMasa(),
                Products: cart,
                TotalPrice: 0,
                Sezlong: false
            }
            var data = JSON.stringify([model]);
            PostQuery("/api/AddOrder", JSON.stringify(data), function (response) {
                if (response.Error) {
                    if (response.Error == "NetWork Error") {

                    } else {
                        MessageBox(response.Error, "danger");
                        t.IsLoading(false);
                        t.FinishState(false);
                    }
                } else {
                    t.IsLoading(false);
                    t.CartItems([]);
                    t.Navigation(screens.finish_screen);
                    t.FinishState(true);
                }
            }, function () {

            }, "POST");
        } else {
            return;
        }
    }
    // end cart items

    // "success": true, "fail": false 
    t.FinishState = ko.observable(true);

    // sayfa screens.menu_screen ise ürünlerin detayının açılıp veya kapanması için tetiklenir.
    t.OnCollapse = function (data, event) {
        var collapse = data.collapse();
        if (!collapse)
            $(".product-line").map(function (i) { $($(".product-line")[i]).addClass("unSelectedItem") });
        if (collapse)
            $(".product-line").map(function (i) { $($(".product-line")[i]).removeClass("unSelectedItem") });

        data.collapse(!collapse);
        $(event.target.parentElement.parentElement.parentElement).removeClass("unSelectedItem");
    }

    // login bilgisi bu objectte tutulur.
    t.LoginInfo = { Password: null, Roles: [], DepartNo: null };

    // uygulamada gösterilecek olan view in belirlendiği object eğer false ise login sayfası açılarak kullunıcının login olması sağlanır.
    t.Authorize = ko.pureComputed(function () {
        if (window.localStorage) {
            var user = JSON.parse(window.localStorage.getItem("user"))
            if (user) {
                t.LoginInfo = new userModel(user);
                return true;
            } else {
                t.LoginInfo = new userModel();
                t.IsLoading(false);
                return false;
            }
        } else {
            return false;
        }
    });

    // login sayfasındaki login olmak için tetiklenen fonksiyon
    t.Login = function () {
        t.LoginInfo.Login(function (response) {
            if (response.Error) {
                t.LoginInfo.NotFound(true);
                t.LoginInfo.ErrorMessage(response.Error);
            } else if (response.user) {
                t.DepNo(undefined);
                t.Password(undefined);
                t.loginError.showAllMessages(false)
                t.LoginInfo.ID(response.user.ID);
                t.LoginInfo.UserName(response.user.UserName);
                t.LoginInfo.RoleId(response.user.RoleId);
                t.LoginInfo.RoleName(convertToRoleName(response.user.RoleName));
                if (response.roles.length > 0) {
                    var roles = response.roles.filter(function (r) {
                        return r.UseRole == true;
                    });
                    if (response.roles.length == roles.length) {
                        response.roles.push({ RoleId: 6, Name: "CanEdit", UseRole: true });
                    }
                    t.LoginInfo.Roles(response.roles);
                }
                ;
                var l = JSON.stringify(ko.toJS(model.LoginInfo));
                if (window.localStorage) {

                    window.localStorage.setItem("user", l);
                    var store = window.localStorage.getItem("user");
                    location.reload();
                    return;
                }
                else {
                   return MessageBox("local storage desteklenmiyor");
                }
                
            }
        })
    }



    
    // ürünlerin  başkete atılması sırasında animasyonun yapılması için tetiklenir.
    t.BasketAnimation = function (event) {
        var clonedItem = null;
        // event varsa detaydan gönderilmemiştir
        if (event) {
            var el = document.getElementById("movingItem");
            if (el)
                el.parentNode.removeChild(el);
            clonedItem = $($(event.target.parentElement.parentElement.parentElement.parentElement).find("img")[0]).clone();
             
        }
        // event yoksa detaydan gönderilmiştir.
        else if(!event) {
            clonedItem = $("#singleProductImg").clone();              
        }
        // bir eleman bulduysan
        if (clonedItem) {
            clonedItem[0].classList.add("movingItem");
            clonedItem[0].setAttribute("id", "movingItem");
            clonedItem[0].style.height = "40px";
            var el = document.getElementById("movingItem");
            if (el)
                el.parentNode.removeChild(el);
            $(clonedItem).appendTo("body");
            return
        }  
            
    }

    // masa listesini tutacak olan array objesi
    t.MasaListesi = ko.observableArray([]);

    // db den okunması ve MasaListesi arrayıne atanması için ve
    // eğer login olunmuş ise veya masa listesi view' ine gidilecek ise tetiklenir.
    t.MasalistesiGetir = function () {
        PostQuery("/api/DeskList", { "departmentId": t.LoginInfo.DepartNo() }, function (res) {
            if (res && Array.isArray(res.desks)) {
                res.desks.map(function (item) {
                    item.DOLU = ko.observable(item.DOLU);
                    item.FISCOUTER = ko.observable(item.FISCOUTER);
                });
                t.MasaListesi(res.desks);
            } else {
                console.log(res);
            }
        });
    }

    // navigasyonun screens.masalar_screen olarak set edilmesi (görünen sayfaını screens.masalar_screen view i olması) ve masalistesinin en güncel halinin db den okunması
    t.MasalistesiniAc = function () {
        t.MasalistesiGetir();
        if (t.MasaListesi().length > 0) {
            t.Navigation(screens.masalar_screen);
        } else {
            console.log("Masalar gelmedi");
        }
        t.AppMenuItems(false);
     
    }

    // ürünlerin yeniden yüklenmesi, cache den silinip yeniden yükleme için kullanılır.
    t.Reload = function () {
        t.IsLoading(true);
        window.localStorage.removeItem("AllData");
        t.Load();
        t.IsLoading(false);
        t.Navigation(screens.group_screen);
    }

    // eğer kullanıcı çıkış yapmak istiyorsa ve en son login olan kişi ile çıkış yapmak isteyen kisi departman ve parola bilgisi eşleşiyorsa,
    // uygulamadan çıkış yapmak için kullanılır.
    t.SignOut = function () {
        app.LocalStorage.Remove("user")
        window.location.reload();
    }

    // sepetteki sipariş göndermek için kullanılan butonun textinin ayarlandığı object.
    t.SendButonText = ko.pureComputed(function () {
        if (t.CartItems().length == 0) {
            return "Sipariş Gönder"
        } else {
            return "Siparişleri Gönder"
        }
    })

    // uygulamadaki bazı yeteneklerin kullanımının aktif veya pasif olmasını sağlayan fonksiyon.
    // eğer app a login olan kişi ile örneğin masa listesine gitmek veya,
    // oturumu kapatmak veya ürünleri yeniden yüklemek isteyen kişi aynı mı bunun kontrolünün yapıldığı yer
    t.LoginControl = function () {
        if (t.loginError().length > 0) {
            t.loginError.showAllMessages();
        }
        else {
            if ((t.LoginInfo.DepartNo() == t.DepNo()) && (t.LoginInfo.Password() == t.Password())) {
                t.AppMenuItems(true);
                t.SetDefaultModalOptions();
                t.SelectedMode(modes.garson);
                window.localStorage.setItem("mode", modes.garson);
            } else {
                t.ErrorMessage("Lütfen departman kodunuzu ve parolanızı doğru giriniz");
            }
        }
    }

    // eğer app a login olan kişi ile oturumu kapatmak veya ürünleri yeniden yüklemek isteyen kişi aynı değil ise hata mesajının ekrana yazdırılması için kullanılan object.
    t.ErrorMessage= ko.observable();

    // app a login olunmuş ise ve masa listesine geri dönülmek isteniyor ise açılan login popupundaki parola objesi
    t.Password = ko.observable().extend({ required: true });

    // app a login olunmuş ise ve masa listesine geri dönülmek isteniyor ise açılan login popupundaki DepNo objesi
    t.DepNo = ko.observable().extend({ required: true });

    // eğer app a login olan kişi ile oturumu kapatmak veya ürünleri yeniden yüklemek isteyen kişi,
    // açılan popupdaki zorunlu olan fieldların validasyonunun belirlendiği object.
    t.loginError = ko.validation.group([t.Password, t.DepNo], { deep: true });

    var mode = undefined;
    if (window.localStorage) {
       mode = window.localStorage.getItem("mode");
    }
     //|| undefined;
    t.SelectedMode = ko.observable(mode);

    t.AppConfig = new config(modes.garson);

    t.FileUpload = function (data,event) {
        var formData = GetFormData(event.target);        
        if (formData.Errors.size.length == 0 && formData.Errors.name.length == 0) {
            FileUpload('/home/UploadImage', formData.FormData, function (res) {
                var data = JSON.parse(res)
                if (data.files.length > 0) {
                    for (var i = 0; i < data.files.length; i++) {
                        t.EditableObejct().File(data.files[i].Path);
                    }
                }
            })
        }
        else {
            console.log(formData.Errors);
        }
    }

    t.Edit = function () {
        var data = ko.toJS(t.SelectedSingleProduct());
        t.EditableObejct(new EditViewModel(data));
        t.Navigation(screens.edit_screen);
    }

    t.EditableObejct = ko.observable();

    // screens.edit_screen edilmiş EditableObejct in db ye kaydedilmesi
    t.Save = function () {
        t.IsLoading(true);
        if (t.EditableObejct().Errors().length > 0) {
            t.EditableObejct().Errors.showAllMessages();
        } else {
            var model = ko.toJS(t.EditableObejct());
            //if (model.Action == 'Düzenle') {
                PostQuery("/api/AddDetail", { data: JSON.stringify(model) }, function (res) {
                    if (res.Error) {
                        MessageBox("Değişiklikler sırasında hata oluştu.");
                    } else {
                        MessageBox("Değişiklikler başarı ile kaydedildi.");
                        // şimdilik 
                        app.LocalStorage.Remove("alldata")
                        t.Reload();
                        // daha sonra yeniden yüklemeden js seviyesinde ilgili ürünü bulup güncelleyecek
                    }
                })
           // }
            //else if (model.Action == 'Ekle') {
            //    model.StokGrupID = t.ComputedProductGroup().GKODU;
            //    PostQuery("/api/AddDetail", { data: JSON.stringify(model) }, function (res) {
            //        if (res.Error) {
            //            MessageBox("Ekleme sırasında hata oluştu.");
            //        } else {
            //            MessageBox("Ürün başarı ile kaydedildi.");
            //        }
            //    });
            //}
            //else {
            //    MessageBox('İşlem Gerçekleştirilemedi!');
            //}
        }
        t.IsLoading(false);
        return;
    }

    // bazı viewlerde filtreleme yapmak istiyorsak parametrelere göre dinamik filtre html i olusturur _Filters.cshtml de kullanılır.
    t.Filters = ko.pureComputed(function () {
        switch (t.Navigation()) {
            case screens.group_screen:
                return {
                    items: [
                        FilterModel("Sırala", function () { t.ChangeSort('GADI') }, css.col_12)
                    ]
                };
            case screens.menu_screen:
                return {
                    items: [
                        FilterModel("Ad'a Göre", function () { t.ChangeSort('SADI') }, css.col_4),
                        FilterModel("Fiyat'a Göre", function () { t.ChangeSort('F') }, css.col_4),
                        FilterModel("Kaloriye Göre", function () { t.ChangeSort('Calori') }, css.col_4)
                    ]
                };
            case screens.cart_screen:
                return {
                    items: [
                        FilterModel("Ad'a Göre", function () { t.ChangeSort('SADI') }, css.col_6),
                        FilterModel("Fiyat'a Göre", function () { t.ChangeSort('DisplayPrice') }, css.col_6)
                    ]
                };
            case screens.masalar_screen:
                return {
                    items: [
                        FilterModel("Dolu", function () { t.TableFilter(filters.dolu) }, css.col_3 + css.padding_5),
                        FilterModel("Boş", function () { t.TableFilter(filters.bos) }, css.col_3 + css.padding_5),
                        FilterModel("Tümü", function () { t.TableFilter(filters.tumu) }, css.col_3 + css.padding_5),
                        FilterModel("Yeni Ekle", function () { t.TableFilter(filters.yeni) }, css.col_3 + css.padding_5),

                    ]
                }
            default: return { items: [] }
        }
    });

    // masa listesninde yeni masa oluşturmak için kullanır.
    t.createNewTable = function () {
        var masainput = document.getElementById("newMasa");
        if (masainput.value) {
            var exist = t.MasaListesi().filter(function (f) { return f.MASANO.toLowerCase() == masainput.value.toLowerCase() }).length > 0;
            if (exist) {
                MessageBox("eklemeye çalıştığınız masa zaten var, lütfen benzersiz bir isim belirleyin");
                return;
            } else {
                var model = {
                    ID: -1,
                    MASANO: masainput.value,
                    DOLU: ko.observable(false),
                    SEZLONG: false,
                    FISCOUTER: null,
                    AfterSezlong: ko.observable()
                };
                t.MasaListesi.unshift(model);
                t.SelectMasa(model);
                masainput.value = "";
                t.TableFilter(filters.tumu);
            }
        } else {

        }
    }

    // masa listesindeki filtreleme bu eleman üzerinden yapılır.
    t.TableFilter = ko.observable(filters.tumu);

    t.AdminCurrentAction = ko.observable();

    t.Modes = function () {
        var items = [];
            Object.keys(modes).forEach(function (m) {
                //if (modes[m] != modes.admin && modes[m] != modes.mutfak && modes.mode != modes[m]) {
                if ( modes.mode != modes[m]) {
                    items.push(ModeObject(modes[m], function () { t.ChangeModeWithNavigation(modes[m]) }))
                }
            });
        return { items: SortBy(items, "name", "asc") };
    };

    t.ChangeModeWithNavigation = function (mode, screen) {
        t.SelectedMode(mode);
        t.AppMenuItems(false);
        switch (mode) {
            case modes.admin:
                t.AdminLoad();
                break;
            case modes.mode:
                t.Navigation(screens.appmode_screen);
                break;
            default:
                t.Navigation(screens.masalar_screen);
                break;
        }
        if (window.localStorage && mode == modes.user) {
            window.localStorage.setItem("mode", t.SelectedMode());
        }
        return;
    };

    t.AdminLoad = function () {
        t.Navigation(screens.admin_screen);
        //t.Load();
    }

    //generic navbaroptions
    t.NavbarOptions = function () {
        var items = [],
            changemode = "Uygulama modunu değiştir",
            signout = "Oturumu Kapat",
            masalist = "Masa Listesine dön",
            reload = "Ürünleri Yeniden Yükle";     
        switch (t.SelectedMode()) {
            case undefined:
                break;
            case modes.admin:
                items.push(NavigationModel(icons.empty, function () { t.ChangeModeWithNavigation(modes.mode, screens.appmode_screen); }, changemode, ""));
                items.push(NavigationModel(icons.empty, function () { t.SignOut(); }, signout, ""));
                break;
            case modes.kasiyer:
                items.push(NavigationModel(icons.empty, function () { t.MasalistesiniAc(); }, masalist, ""));
                items.push(NavigationModel(icons.empty, function () { t.ChangeModeWithNavigation(modes.mode, screens.masalar_screen); }, changemode, ""));
                items.push(NavigationModel(icons.empty, function () { t.SignOut(); }, signout, ""));
                break;
            case modes.mutfak:
                items.push(NavigationModel(icons.empty, function () { t.MasalistesiniAc(); }, masalist, ""));
                items.push(NavigationModel(icons.empty, function () { t.ChangeModeWithNavigation(modes.mode, screens.masalar_screen); }, changemode, ""));
                items.push(NavigationModel(icons.empty, function () { t.SignOut(); }, signout, ""));
                break;
            case modes.user:
                items.push(NavigationModel(icons.empty, function () { t.MasalistesiniAc(); }, masalist, ""));
                items.push(NavigationModel(icons.empty, function () { t.ChangeModeWithNavigation(modes.mode, screens.masalar_screen); }, changemode, ""));
                items.push(NavigationModel(icons.empty, function () { t.SignOut(); }, signout, ""));
                break;
            default:
                items.push(NavigationModel(icons.empty, function () { t.MasalistesiniAc(); }, masalist, ""));
                items.push(NavigationModel(icons.empty, function () { t.ChangeModeWithNavigation(modes.mode, screens.appmode_screen); }, changemode, ""));
                items.push(NavigationModel(icons.empty, function () { t.Reload(); }, reload, ""));
                items.push(NavigationModel(icons.empty, function () { t.SignOut(); }, signout, ""));
                break;
            };
        return { items: items };
    }

    t.PaymentTypes = ko.observableArray([]);

    // bu kod daha temiz oldu.
    t.GetPaymentTypes = function () {
        var pt = window.localStorage.getItem("PaymentTypesEmenu");

        if (pt !== "null" && pt != null) {
            var list = JSON.parse(pt);
            if (list.length > 0) {
                // parçalı ödeme listesi oluştur ne kadar ödeme tipi varsa bunları p. için de ayrıca sun.
                var parçaliOdeme = { key: "Parçalı Ödeme", list: list };
                list.push(parçaliOdeme);
                t.PaymentTypes(list);
            }            
            return;
        } else {
            PostQuery("/api/GetPaymentTypes", null, function (res) {
                if (res && res.paymentTypes && Array.isArray(res.paymentTypes)) {
                   // var types = GroupBy(res.paymentTypes.map(function (item) { item.Type == null ? item.Type = item.Name : null; return item;}), "Type").filter(function (p) { return p.key != "Hesaptan Ödeme" });
                    var types = GroupBy(res.paymentTypes.filter(function (item) { return item.Name != "HESABA GONDER" }), "Type").filter(function (p) { return p.key != "Hesaptan Ödeme" });

                    window.localStorage.setItem("PaymentTypesEmenu", JSON.stringify(types));

                    var parçaliOdeme = { key: "Parçalı Ödeme", list: types };
                    // parçalı ödeme listesi oluştur ne kadar ödeme tipi varsa bunları p. için de ayrıca sun.
                    types.push(parçaliOdeme);

                    t.PaymentTypes(types);

                }
            });
        }
    }

    t.TransfereMusaitMasalistesi = ko.pureComputed(function () {
        if (t.MasaListesi().length > 0) {
            return t.MasaListesi().filter(function (m) { return m.DOLU() == true && m.MASANO != t.SelectedMasa() });
        } else {
            return [];
        }
    });

    // adisyon da urun bazlı transferi gerçekleştiren fonksiyon
    t.transferTo = function (data,currentIndex,parentIndex) {
        // ajax isteği  atmak için model oluştur.
        var to = data.TransferTo() && data.TransferTo().MASANO || null,
            productId = data.ID() || null,
            transferQuantity = data.TransferQuantity() || null;
        if (to != null && productId != null && transferQuantity != null) {        
            var model = { From: t.SelectedMasa(), To: to, ProductId: productId, Quantity: transferQuantity, DepNo: t.LoginInfo.DepartNo() };
            PostQuery("/api/UrunTransfer", model, function (res) {
                if (res.Error) {
                    MessageBox(res.Error);
                } else {
                    var message = t.SelectedMasa() + " nolu masadan " + to + " nolu masaya " + transferQuantity + " adet ürün transferi başarı ile gerçekleşti";
                    MessageBox(message);
                    var alist = t.AdisyonListesi()[parentIndex];
                    var lastPrice = alist.TotalPrice() - data.Price() * data.TransferQuantity();
                    if (data.Quantity() == data.TransferQuantity()) {
                        alist.list.splice(currentIndex, 1);
                        alist.TotalPrice(lastPrice);
                        return
                    } else {
                        data.Quantity(data.Quantity() - data.TransferQuantity());
                        alist.TotalPrice(lastPrice);
                        return;
                    }
                    return;
                }
            });
        } else {
            MessageBox("lütfen transfer parametrelerini doldurunuz");
            return;
        }
    }

    // masa ile herhangi bir işlem yapılmadan önce masa seçilmiş  mi diye bak seçilmemiş ise uyarı çıkart
    t.masaControl = function () {
        if (!t.SelectedMasa()) {
            MessageBox(messages.masasec);
            return false;
        } else {
            return true;
        }
    }

    // adisyon ekranında kimin transfer yapabileceğinin karar verildiği object
    t.TransferEnabled = function () {
        switch (t.SelectedMode()) {
            case modes.user:
                return false;
                break;
            case modes.mutfak:
                return false
            default:
                return true;
                break;
        }
    }
}
//sayfa scroll edildiğinde searchbox alanı gizlenir veya gösterilir
$(function () {
    var cubuk_seviye = $(document).scrollTop();
    var header_yuksekligi = $('.yapiskan').outerHeight();

    $(window).scroll(function () {
        var kaydirma_cubugu = $(document).scrollTop();

        if (kaydirma_cubugu > header_yuksekligi) { $('.yapiskan').addClass('gizle'); }
        else { $('.yapiskan').removeClass('gizle'); }

        if (kaydirma_cubugu > cubuk_seviye) { $('.yapiskan').removeClass('sabit'); }
        else { $('.yapiskan').addClass('sabit'); }

        cubuk_seviye = $(document).scrollTop();
    });
});

// app config object
var config = function (_mode) {
    return { mode: _mode || modes.garson_mode }
}

var basketModel = function (data) {
    var t = this;
    t.AccNo = ko.observable(data && data.AccNo);
    t.D = ko.observable(data && data.D);
    t.F = ko.observable(data && data.F || 0);
    t.DEP = ko.observable(data && data.DEP);
    t.Extras = ko.observable(data && data.Extras);
    t.PSURE = ko.observable(data && data.PSURE);
    t.Quantity = ko.observable(data && data.Quantity && data.Quantity() || 0);
    t.Query = ko.observable(data && data.Query);
    t.SADI = ko.observable(data && data.SADI);
    t.SID = ko.observable(data && data.SID);
    t.SR = ko.observable(data && data.SR);
    t.SSCK = ko.observable(data && data.SSCK);
    t.SSURE = ko.observable(data && data.SSURE);
    t.SR = ko.observable(data && data.SR);
    t.Details = ko.observable(data && data.Details || {});
    t.DisplayPrice = ko.pureComputed(function () {
        return t.F() * t.Quantity();
    });
    t.collapse = ko.observable(false);
}

var productModel = function (data) {
    return {
        AccNo : data && data.AccNo,
        D :data && data.D,
        F : data && data.F || 0,
        DEP : data && data.DEP,
        Extras : data && data.Extras,
        PSURE : data && data.PSURE,
        Quantity :ko.observable(data && data.Quantity || 0),
        Query : data && data.Query,
        SADI : data && data.SADI,
        SID : data && data.SID,
        SR : data && data.SR,
        SSCK : data && data.SSCK,
        SSURE : data && data.SSURE,
        SR : data && data.SR,
        Details : data && data.Details || {},
        collapse :ko.observable(false),
    }
}

var EditViewModel = function (data) {   
    var self = this;
    self.Action = ko.observable(model.SelectedAction());
    self.Id = ko.observable(data && data.SID);
    self.Name = ko.observable(data && data.SADI).extend({ required: true });
    self.File = ko.observable(data && data.Details.ImgPath);
    self.Price = ko.observable(data && data.F).extend({ required: true });
    self.Currency = ko.observable(data && data.D || "TL");
    self.Sicaklik = ko.observable(data && data.SSCK);
    self.HazirlanmaSuresi = ko.observable(data && data.PSURE);
    self.BeklelemeSuresi = ko.observable(data && data.SSURE);
    self.Description = ko.observable(data && data.Details.Description);
    self.Calori = ko.observable(data && data.Calori);
    self.Errors = ko.validation.group(self, { deep: true });
}

var ModeObject = function (_name,_callback,_css) {
    return { name: _name, callback: _callback, css: _css };
}

var paymentModel = function (_items,_price,_type,_types) {
    return {
        Items: _items || [],
        Price: ko.observable(_price || 0),
        Type: ko.observable(_type || null),
        Types: ko.observable(_types || [])

    }
}