function ShowModal(_url, _class, _title, _buttons,bindHtml) {
    // urf = fromurl,
    // class = small , medium(default),large,xlarge;
    // title = page title,
    // buttons = type array, button objects;
    var m = Element.FindById("modal-div");
    if (!m) {
        m = Element.Create("div");
        m.setAttribute("id", "modal-div");
    }
    var modalContent = '<div class="modal" tabindex="-1" id="modal" role="dialog">' +
                            '<div class="modal-dialog ' + (_class || '') + '" role="document">' +
                                '<div class="modal-content">' +
                                    '<div class="modal-header">' +
                                        '<div class="col-xs-10 col-sm-10 col-md-10"><h5 class="modal-title"> ' + (_title || '' ) + '</h5></div>' +  
                                        '<div class="col-xs-2 col-sm-2 col-md-2"> <button type= "button" class="close" data-dismiss="modal" aria-label="Close"><i class="material-icons">close</i></button></div>'+
                                    '</div>' +
                                    '<div class="modal-body" id="mb"></div>'+
                                    '<div class="modal-footer" id="mf"></div>' +
                                '</div>' +
                            '</div>' +
                        '</div>';
    m.innerHTML = modalContent;
    var root = null;
    if (bindHtml) {
        root = document.getElementById(bindHtml);

    } else {
        root = document.body;
    }
    root.appendChild(m);

    if (_url) {
        GetHtmlFromUrl(_url, function (res) {
           
            if (res) {
                var mb = Element.FindById("mb");
                mb.innerHTML = res;
                var mf = Element.FindById("mf");
                mf.innerHTML = "";
                if (_buttons && _buttons.length > 0) {
                    for (var i = 0; i < _buttons.length; i++) {
                        mf.innerHTML += _buttons[i];
                    }
                } else {
                    //mf.innerHTML = '<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>';
                }
            }
            $("#modal").modal();
        })
    }

}

function GetHtmlFromUrl(url, callback) {
    if (url) {
        return $.get(url, callback || function (res) {
            console.log(res);
        })
    }
    else {
        return undefined;
    }
}

function NextPage(currentTemplateId, targetTemplateId, beforeCallback, afterCallback) {
    if (typeof (beforeCallback) == "function") {
        beforeCallback();
    }
    var curTemp = Element.FindById(currentTemplateId);
    var tarTemp = Element.FindById(targetTemplateId);
    if (curTemp && tarTemp) {
        curTemp.style.display = "none";
        tarTemp.style.display = "block";
        if (typeof (afterCallback) == "function") {
            afterCallback();
        }
    }
}

ko.bindingHandlers.returnAction = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var value = ko.utils.unwrapObservable(valueAccessor());

        $(element).keydown(function (e) {
            if (e.which === 13) {
                value(viewModel);
            }
        });
    }
};

ko.bindingHandlers.placeholder = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var underlyingObservable = valueAccessor();
        ko.applyBindingsToNode(element, { attr: { placeholder: underlyingObservable } });
    },
    update: function (element, valueAccessor, allBindingsAccessor) {
        debugger
        var underlyingObservable = valueAccessor();
        ko.applyBindingsToNode(element, { attr: { placeholder: underlyingObservable } });
    }
};

ko.bindingHandlers.doubleClick = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var handler = valueAccessor(),
            delay = 200,
            clickTimeout = false;

        $(element).click(function () {
            if (clickTimeout !== false) {
                handler.call(viewModel);
                clickTimeout = false;
            } else {
                clickTimeout = setTimeout(function () {
                    clickTimeout = false;
                }, delay);
            }
        });
    }
};

function PostQuery(Url, Json, SuccessCallback, errorCallback ,Method) {
    return $.ajax({
        type: Method || 'GET',
        url: Url,
        data: Json || {},
        dataType: "json",
        contentType: 'application/json; charset=utf-8',
        success: SuccessCallback,
        async: false,
        error: errorCallback || function (xhr, status, errorThrown) {
            console.log(xhr.responseText);
        }
    });
}

ko.bindingHandlers.modal = {
    init: function (element, optionsAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var $element = $(element);

        if ($element.attr("tabindex") === undefined) {
            $element.attr("tabindex", -1);
        }

        $element.modal(ko.toJS(optionsAccessor()));

        $element.on("hidden.bs.modal", function () {
            var options = ko.utils.unwrapObservable(optionsAccessor());
            return false;
        });

        $(document).on("keyup", function (e) {
            return false;
            if (e.which === 27) {
                $element.modal("hide");
            }
        });

        // hide elements inside modal unless we are showing it
        var _showAccessor = showAccessor.bind(optionsAccessor, optionsAccessor);
        ko.bindingHandlers["if"].init(element, _showAccessor, allBindingsAccessor, viewModel, bindingContext);
    },
    update: function (element, optionsAccessor) {
        var _showAccessor = showAccessor.bind(optionsAccessor, optionsAccessor);

        $(element).modal(_showAccessor() ? "show" : "hide");
    }
};

function showAccessor(accessor) {
    var options = ko.utils.unwrapObservable(accessor());
    return ko.utils.unwrapObservable(options.show);
}

ko.bindingHandlers.fadeSwitcher = {
    init: function (element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        element.setAttribute('previousValue', value);
        ko.bindingHandlers.text.update(element, ko.observable(value));
    },
    update: function (element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        var previousValue = element.getAttribute('previousValue');
        if (value !== previousValue) {
            $(element).fadeOut('fast', function () {
                ko.bindingHandlers.text.update(element, ko.observable(value));
                $(element).fadeIn();
            });
            element.setAttribute('previousValue', value);
        }
    }
};

var Element = {
    Create: function (tagName) {
        if (tagName) {
            return document.createElement(tagName);
        } else {
            return document.createElement("div");
        }
    },
    Remove: function (elementId) {
        var element = document.getElementById(elementId);
        if (element) {
            element.parentNode.removeChild(element)
        } else {
            return;
        }
    },
    RemoveByClassNames: function (ClassNames) {
        var elements = Element.getElementsByClassName(ClassNames);
        if (elements.length > 0) {
            for (var i = 0; i < elements.length; i++) {
                elements[i].parentNode.removeChild(elements[i]);
            }
        }
    },
    FindById: function (elementId) {
        return document.getElementById(elementId);
    },
    FindByTagNames: function (tagName) {
        return document.getElementsByName(tagName);
    },
    FindByClassNames: function (className) {
        return document.getElementsByClassName(className);
    },
    FindByNames: function (name) {
        return document.getElementsByName(name);
    },
}

ko.bindingHandlers.stopBinding = {
    init: function () {
        return { controlsDescendantBindings: true };
    }
};

var GroupBy = function (xs, key) {
    if (xs == undefined) {
        return [];
    } else {
        var data = xs.reduce(function (rv, x) {
            (rv[x[key]] = rv[x[key]] || []).push(x);
            return rv;
        }, {});
        return Object.keys(data).map(function (itm) {
            return { key: itm, list: data[itm] };
        })
    }
};

var MessageBox = function (text, modalType) {
    var _class = "";
    switch (modalType) {
        case 'success':
            _class = "modal-success"
            break;
        case 'danger':
            _class = "modal-danger"
            break;
        case 'primary':
            _class = "modal-primary"
            break;
        default:
            _class = "modal-default"
            break;
    }

    var closeImg = _class == "modal-default" ? "close.png" : "closewhite.png";
    var modal = document.getElementById("msgModal");
    if (!modal) {
        modal = document.createElement("div");
        modal.setAttribute("id", "msgModal");
        modal.setAttribute("class", "modal fade");
        modal.setAttribute("role", "dialog");
        modal.style.display = "block;";
    }
    var modalContent = '<div class="modal-dialog">' +
        '<div class="modal-content">' +
        '<div class="modal-header ' + _class + '">' +
        '<button type="button" class="close" data-dismiss="modal">' +
        '<img src="../../../Upload/icon/' + closeImg + '" height="20"/>' +
        '</button>' +
        '<h4 class="mboxText" style="white-space: inherit !important;">' + text + '</h4>' +
        '</div>' +
        '</div>';
    modal.innerHTML = modalContent;
    if (!document.getElementById("msgModal")) {
        document.getElementsByTagName('body')[0].appendChild(modal);
    }
    $(modal).modal();
    return;
}

var ShowLoader = function () {
    var loader = document.getElementById("loader");
    if (!loader) {
        loader = document.createElement("div");
        loader.setAttribute("id", "loader");
        loader.innerHTML = "<div id=\"loaderContent\"></div>";
        loader.innerHTML += "<span>Yükleniyor..</span>";
    }
    if (!document.getElementById("loader")) {
        document.getElementsByTagName('body')[0].appendChild(loader);
    }
    loader.style.display = "flex";
    return;
}

var HideLoader = function () {
    var loader = document.getElementById("loader");
    if (loader)
        loader.style.display = "none";
    return;
}

var ShowConfirm = function (message,yesCallback) {
    //var closeImg = "close.png",
      var _class = "modal-default";
    var modal = document.getElementById("msgConfirm");
    if (!modal) {
        modal = document.createElement("div");
        modal.setAttribute("id", "msgConfirm");
        modal.setAttribute("class", "modal fade");
        modal.setAttribute("role", "dialog");
        modal.style.display = "block;";
    }
    var yes = "";
    if (yesCallback) {
        yes = '<button type="button" class="btn btn-default" data-dismiss="modal" onclick="(' + yesCallback + ')();" >Evet</button>';
    }    
    var modalContent = '<div class="modal-dialog">' +
        '<div class="modal-content">' +
            '<div class="modal-header ' + _class + '">' +
            '<button type="button" class="close" data-dismiss="modal">' +
            '</button>' +
            '<h4 class="mboxText" style="white-space: inherit !important;">' + message + '</h4>' +
            '</div>' +
            '<div class="modal-footer">' + yes+
            '<button type="button" class="btn btn-default" data-dismiss="modal">Hayır</button>' +
        '</div>' +
        '</div>';
    modal.innerHTML = modalContent;
    if (!document.getElementById("msgConfirm")) {
        document.getElementsByTagName('body')[0].appendChild(modal);
    }
    $(modal).modal();
    return;
}

ko.bindingHandlers.fadedIf = {
    init: function (element, valueAccessor, allBindingsAccessor, data, bindingContext) {
        // Initially set the element to be instantly visible/hidden depending on the value
        var value = valueAccessor();
        //If the value is a normal function make it a computed so that it updates properly
        if (!ko.isObservable(value)) {
            value = ko.computed({ read: valueAccessor });
        }
        //attach our observable property to the accessor so that it can be used in the update function
        valueAccessor.domShown = ko.observable(ko.unwrap(value));

        //Wrap any contents of the element in a new div, and then bind that div using the "if" binding.
        //This way the element and its event hooks for fading in/out never leaves the dom, but all content does.
        //it also prevents applying multiple bindings to the same element.
        var contentWrapper = $(element).children().wrapAll(document.createElement("div")).parent()[0];
        ko.applyBindingAccessorsToNode(contentWrapper, { 'if': function () { return valueAccessor.domShown } }, bindingContext);
    },
    update: function (element, valueAccessor) {
        // Whenever the value subsequently changes, slowly fade the element in or out
        var value = valueAccessor();

        if (ko.unwrap(value)) {
            valueAccessor.domShown(true); //restore the element to the DOM
            $(element).fadeIn();
        } else {
            $(element).fadeOut({
                complete: function () {
                    valueAccessor.domShown(false); //remove the element from the DOM
                }
            });
        }
    }
};

ko.bindingHandlers.fadeVisible = {
    init: function (element, valueAccessor) {
        // Initially set the element to be instantly visible/hidden depending on the value
        var value = valueAccessor();
        $(element).toggle(ko.unwrap(value)); // Use "unwrapObservable" so we can handle values that may or may not be observable
    },
    update: function (element, valueAccessor) {
        // Whenever the value subsequently changes, slowly fade the element in or out
        var value = valueAccessor();
        ko.unwrap(value) ? $(element).fadeIn('slow', function () {
            $(this).show();
        }) : $(element).fadeOut('slow', function () {
                $(this).hide();
        });
    }
};

function GetFormData(e) {
    var Result = {
        Errors: {
            name: [],
            size: []
        },
        FormData: null
    }
    var files = e.files;
    for (var i = 0; i < files.length; i++) {
        var file = e.files[i],
            nameResult = CheckFileName(file.name),
            sizeResult = FileSizeControl(file);
        if (!sizeResult.success) {
            Result.Errors.size.push({ "name": file.name, "size": sizeResult.size });
        }
        if (!nameResult) {
            Result.Errors.name.push({ "name": file.name });
        }
    }
    var imageType = /image.*/;
    var form_data = new FormData();
    for (var i = 0; i < files.length; i++) {
        if (!files[i].type.match(imageType)) return;
        form_data.append('file' + i, files[i]);
    }
    Result.FormData = form_data;
    return Result;
};

function FileSizeControl(file) {
    var Result = {
        success: false,
        size: 0
    },
        kb = file.size / 1024,
        mb = parseFloat(kb / 1024).toFixed(2);

    if (mb < 0.5) {
        Result.success = true;
        Result.size = mb || "0";
    } else {
        Result.success = false;
        Result.size = mb || "0";
    }
    return Result;
}

function CheckFileName(filename) {
    var ext = GetExtension(filename);
    switch (ext.toLowerCase()) {
        case 'jpg':
        case 'jpeg':
        case 'gif':
        case 'bmp':
        case 'png':
        case 'bmp':
        case 'tif':
            //etc
            return true;
    }
    return false;
}

function GetExtension(filename) {
    var parts = filename.split('.');
    return parts[parts.length - 1];
}

function FileUpload(url, formData, successCallback) {
    $.ajax({
        url: url,
        cache: false,
        contentType: false,
        processData: false,
        data: formData,
        type: 'POST',
        success: successCallback,
        error: function (error) {
            console.log(error);
        }
    });
}

var SortBy = function (array, key, type) {
    var data = array.sort(function (a, b) {
        var x = a[key] && TrToEn(a[key]); var y = b[key] && TrToEn(b[key]);
        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });
    switch (type) {
        case 'desc':
            return data.reverse();
        default:
            return data;
    }
}

var TrToEn = function (_val) {
    var charMap = {
        Ç: 'C', Ö: 'O', Ş: 'S', İ: 'I', I: 'i', Ü: 'U', Ğ: 'G', ç: 'c', ö: 'o', ş: 's', ı: 'i', ü: 'u', ğ: 'g'
    };
    var val = typeof (_val) == "function" ? _val() : _val;

    return typeof (val) === "number" ? val : val.replace(' ', '').split('').map(function (item) {
        return charMap[item] || item;
    }).join('');
}

var scrollUp = function () {
    var body = $("html, body");
    body.stop().animate({ scrollTop: 0 }, 500, 'swing', function () { });
}

var scrollDown = function (elHeight) {
    var result = screen.height - elHeight;
    if (result < 0) {
        var body = $("html, body");
        body.stop().animate({ scrollTop: screen.height + result }, 500, 'swing', function () { });
    }

}

var NavigationModel = function (icon, callback, text, css) {
    var errors = [];
    typeof (icon) === "string" || typeof (icon) ===  "undefined" ? null : errors.push({ icon: "invalid format, please use type of string" });
    typeof (callback) === "function" || typeof (callback) === "undefined" ? null : errors.push({ callback: "invalid format, please use type of function" });
    typeof (text) === "string" || typeof (text) === "undefined" ? null : errors.push({ text: "invalid format, please use type of string" });
    typeof (css) === "string" || typeof (css) === "undefined" ? null : errors.push({ css: "invalid format, please use type of string" });
    if (errors.length > 0) {
        console.log(errors);
    }
    return {
        icon: icon || "",
        click: callback || function () { return console.log(""); },
        text: text || "",
        class: css || 'col-sm-12 col-xs-12 col-md-12',
    };
}

var SearchBoxModel = function (_canUse, _textInput, _placeHolder, _clearCallback, _searchBoxCallback) {
    return {
        canUse: _canUse || false,
        textInput: _textInput || undefined,
        clear: _clearCallback || function () { return null },
        search: _searchBoxCallback || function () { return null },
        placeHolder: _placeHolder || "Ara.."
    }
}

var FilterModel = function (_name, _callback, _class) {
    return {
        name: _name || "", click: _callback || function () { }, css: _class || css.col_12
    };
}

var Languages = {
    tr: { name: "Ad", lastName: "Soyad" },
    en: { name: "Name", lastName: "Lastname" }
}

// ön tarafta seçilmiş olan dil seçeneğini getirecek şimdilik default tr getirsin.
var currentLang = function () {
    return "tr";
}
var translate = function (key) {
    var selectedLang = currentLang();
    return Languages[selectedLang][key];
}

Array.prototype.where = function (condition) { return this.filter(function (item) { return item == condition }) };

Array.prototype.toObject = function () { var arr = this; var rv = {}; for (var i = 0; i < arr.length; ++i) rv[i] = arr[i]; return rv; };

var RoleName = {
    SEF: "ADMIN",
    GARSON: "GARSON",
    KASIYER: "KASIYER",
    MUTFAK: "MUTFAK" || "BAR",
    USER: "USER"
}
var convertToRoleName = function (name) {
    if (RoleName[name]) {
        return RoleName[name];
    } else {
        return "Anonim";
    }
}