function CrudUiController(dataType,baseUrl) {
    //This function is same as a constructer
    this._dataType = dataType;
    this._baseUrl = baseUrl;
    this._readUrl = this._baseUrl + "/Ajax" + this._dataType + "Read"
    this._saveUrl = this._baseUrl + "/Ajax" + this._dataType + "Save"
    this._deleteUrl = this._baseUrl + "/Ajax" + this._dataType + "Delete"
    this._idAddButton = "#addButton" + dataType;
    this._idMessageBox = ".messageBox" + dataType;
    this._idForm = "#form" + dataType;
    this._idOverlay = "#overlay" + dataType;
    this._successMessage = "Item successfully saved";
    this._successRemovedMessage = "Item successfully removed";
    this._readTemplate = '#readTemplate'+ dataType;
    this._readPlaceHolder = '#readPlaceHolder' + dataType;
    this._formTemplate = '#formTemplate' + dataType;
    this._formPlaceHolder = "#formPlaceHolder" + dataType;
    this._formSaveToId = null;
    this._tplRead = '';
    this._tplForm = '';
    this._rows = new Array();
    this._messageBoxTimeout = null;
}

CrudUiController.prototype.Init = function () {
    this.CacheTemplates();
    this._rows = new Array();
    $(this._idOverlay).overlay({
        mask: {
            color: '#aaaaaa',
            loadSpeed: 200,
            opacity: 0.9
        },
        closeOnClick: false
    });
    $(this._idForm).submit(function () {
        this.Save();
        return false;
    });
}
CrudUiController.prototype.CacheTemplates = function () {
    this._tplRead = $(this._readTemplate).template();
    this._tplForm = $(this._formTemplate).template();
}

CrudUiController.prototype.Read = function () {
    //this.AjaxStart(this._readPlaceHolder);
    $.ajax({
        url: this._readUrl,
        dataType: 'json',
        type: "POST",
        cache: false,
        context: this,
        success: this.ReadSuccess,
        error: function (xhr, text, err) {
            this.AjaxStop();
            this.DisplayFailure("Error loading: " + this._readUrl + " " + xhr.status + " " + err);
        }
    });
}

CrudUiController.prototype.ReadSuccess = function (result, textStatus, xhr) {

    if (result.IsValid) {
        $(this._readPlaceHolder).html('');
        this._rows = new Array();
        readTemplate = this._readTemplate;
        for (k = 0; k < result.Value.length; k++) {
            this.AddItem(result.Value[k]);
        }
        this.OnReadSuccess(this._rows);
    }
    else {
        this.DisplayFailure(result.ErrorMessage);
    }

    
}

CrudUiController.prototype.Save = function () {
    if ($(this._idForm).valid()) {
        this.AjaxStart(this._idOverlay);
        $.ajax({
            url: this._saveUrl,
            dataType: 'json',
            type: "POST",
            data: $(this._idForm).serialize(),
            cache: false,
            context: this,
            success: this.SaveSuccess,
            error: function (xhr, text, err) {
                this.AjaxStop();
                this.DisplayFailure("Error loading: " + this._readUrl + " " + xhr.status + " " + err);
            }

        });
    }
    return false;
}

CrudUiController.prototype.SaveSuccess = function (result) {
    try {
        this.AjaxStop();
        if (result.IsValid) {
            $('.close').click();
            if (this._formSaveToId == null) {
                this.AddItem(result.Value);
            }
            else {
                result.Value.objkey = this._rows.length;
                this._rows.push(result.Value);
                replacedValues = $.tmpl(this._tplRead, result.Value);
                $(this._formSaveToId).replaceWith(replacedValues);
            }
            this.OnSaveSuccess(result.Value);
            this.DisplaySuccess(this._successMessage);
        }
        else {
            this.DisplayFailure(result.ErrorMessage);
        }
    }
    catch (err) {
        this.DisplayFailure(err);
    }
}

CrudUiController.prototype.Delete = function (htmlRefToRemove, data) {

    var answer = confirm("Please confirm that you would like to remove this item");
    if (answer) {
        $.ajax({
            url: this._deleteUrl,
            dataType: 'json',
            type: "POST",
            cache: false,
            context: this,
            data: data,
            success: function (data) {
                this.DeleteSuccess(data, htmlRefToRemove);
            },
            error: function (xhr, text, err) {
                this.AjaxStop();
                this.DisplayFailure("Error loading: " + this._readUrl + " " + xhr.status + " " + err);
            }
        });
        $(htmlRefToRemove).fadeOut('slow');
    }
    return false;
}



CrudUiController.prototype.DeleteSuccess = function (result, htmlRefToRemove) {
    try {
        if (result.IsValid) {
            this.DisplaySuccess(this._successRemovedMessage);
            this.OnDeleteSuccess(result.Value);
        }
        else {
            $(htmlRefToRemove).show();
            this.DisplayFailure(result.ErrorMessage);
        }
    }
    catch (err) {
        this.DisplayFailure(err);
    }
}

CrudUiController.prototype.AddItem = function (value) {
    value.objkey = this._rows.length;
    this._rows.push(value);
    $.tmpl(this._tplRead, value).appendTo(this._readPlaceHolder);
}

CrudUiController.prototype.AddNewItem = function () {
    this.ShowOverlay(this.GetNew(), "Add", null);
    return false;
}

CrudUiController.prototype.Update = function (htmlRefToUpdate, index) {
    this.ShowOverlay(this._rows[index], "Update", htmlRefToUpdate);
    return false;
}

CrudUiController.prototype.ShowOverlay = function (value, updateType, rowToUpdate) {
    value.updateType = updateType;
    $(this._formPlaceHolder).html($.tmpl(this._tplForm, value));
    this._formSaveToId = rowToUpdate;
    this.AddJavaScriptValidation();

    var $inputs = $(this._idForm + ' select');
    var values = {};
    $inputs.each(function () {
        if ($(this).attr("selectvalue") != null && $(this).attr("selectvalue").length > 0) {
            $(this).val($(this).attr("selectvalue"))
        }
    });
    $(this._idOverlay).overlay().load();
}


CrudUiController.prototype.DisplaySuccess = function (message) {
    this.DisplayMessage(message, "crudSuccess");
}

CrudUiController.prototype.DisplayFailure = function (message) {
    this.DisplayMessage(message, "crudFailure");
}

CrudUiController.prototype.DisplayMessage = function (message, className) {
    $(this._idMessageBox).html(message).fadeIn('slow');
    $(this._idMessageBox).addClass(className, "slow");
    if (this._messageBoxTimeout != null) {
        clearTimeout(this._messageBoxTimeout);
        if (className != "crudSuccess") {
            $(this._idMessageBox).removeClass("crudSuccess");
        }
        if (className != "crudFailure") {
            $(this._idMessageBox).removeClass("crudFailure");
        }
    }
    this._messageBoxTimeout = setTimeout(function (thisObj) { thisObj.HideMessage(className); }, 5000, this);
}

CrudUiController.prototype.HideMessage = function (className) {
    $(this._idMessageBox).hide('slow').delay(3000).html('');
    $(this._idMessageBox).removeClass(className);
    this._messageBoxTimeout = null;
}

//events
CrudUiController.prototype.AjaxStart = function (coverDiv) {
    var offset = $(coverDiv).offset();
    var offset = $(coverDiv).position();

    $("#ajaxCoverLoading").css("top", offset.top)
    $("#ajaxCoverLoading").css("left", offset.left)
    $("#ajaxCoverLoading").width($(coverDiv).width())
    $("#ajaxCoverLoading").height($(coverDiv).height())
    $("#ajaxCoverLoading").fadeTo('slow', 0.8);
}

CrudUiController.prototype.AjaxStop = function () {
    $("#ajaxCoverLoading").fadeOut('slow');
}


CrudUiController.prototype.AddJavaScriptValidation = function () {
}

CrudUiController.prototype.GetNew = function () {
    return {};
}

CrudUiController.prototype.OnSaveSuccess = function (saveItem) {

}

CrudUiController.prototype.OnDeleteSuccess = function (removedItem) {

}

CrudUiController.prototype.OnReadSuccess = function (allRows) {

}
