<commit_before>/**
 * Class of managing Filtering and displaying of records.
 *
 * @returns {Records}
 */
function Records() {
    /**
     * Object of datatable.
     */
//	this.oTable = null;
    /**
     * URL for managing calls of datatable
     * @type {string}
     */
    var ajaxSource = null;
    var pageUrl = null;
    var selfObj = this;
    var Filters = new Object();
    var customFieldName = 'All';
    var customColumnName = 'all';
    var ajaxSaveStateUrl = null;
    var selectAllRecords = false;
    /**
     * Set the ajax URL of datatable.
     * @param {string} source
     *
     */
    this.setAjaxSource = function (source) {
        ajaxSource = source;

    }
    /**
     * Set the ajax URL for selected rows of datatable.
     * @param {string} source
     *
     */
    this.setAjaxSaveStateUrl = function (source) {
        ajaxSaveStateUrl = source;

    }
    /**
     * Set the page url.
     * @param {string} url
     *
     */
    this.setPageUrl = function (url) {
        pageUrl = url;

    }
    /**
     * Initialize the datatable.
     *
     */
    this.initDataTable = function () {
        // check the existence of table on which we are going to apply datatable.
        if ($('#records').length > 0)
        {
            // Modify css for managing view.
//			$('#container').removeClass('container');
//			$('#container').css('margin', '20px');
            var selected = [];
            oTable =
                    $('#records').dataTable(
                    {
                        "dom": '<"top"p><"clear">tir<"bottom"p>',
                        "bProcessing": true,
                        "bServerSide": true,
                        retrieve: true,
                        destroy: true,
                        "language": {
                            "info": "Showing _START_ - _END_ of _MAX_",
                            "infoFiltered": ''
                        },
                        "aoColumnDefs": [
                            {"bSortable": false, "aTargets": [0]}
                        ],
                        "aaSorting": [],
                        "sAjaxSource": ajaxSource,
                        "bStateSave": true,
//				"fnInitComplete": function () {
//					this.oTable.fnAdjustColumnSizing();
//				},
                        "fnServerData": function (sSource, aoData, fnCallback) {
                            jQuery.getJSON(sSource, aoData, function (json) {
                                fnCallback(json);
                            });
                        },
                        "createdRow": function (row, data, index) {
                            var input = $(row).find("td:first").html();
                            row.id = "row-" + $(input).attr('value');
                        },
                        "ajax": ajaxSaveStateUrl,
                        "rowCallback": function (row, data) {
                            if ($.inArray(row.id, selected) !== -1) {
                                $(row).addClass('selected');
                                $(selected).each(function (key, value) {
                                    var input = $("#" + value + " td:first").html();
                                    $("#" + $(input).attr('id')).attr("checked", "checked");
                                    $("#" + $(input).attr('id')).prop("checked", true);
                                });
                            }
                        }
                    });
            $('#records tbody').on('click', 'tr', function () {
                var id = this.id;
                var index = $.inArray(id, selected);
                if (index === -1) {
                    selected.push(id);
                } else {
                    selected.splice(index, 1);
                }
                $(this).toggleClass('selected', function () {
                    var input = $("#" + id + " td:first").html();
                    if ($(this).hasClass('selected') === true) {
                        $("#" + $(input).attr('id')).attr("checked", "checked");
                        $("#" + $(input).attr('id')).prop("checked", true);
                    } else {
                        $("#" + $(input).attr('id')).removeAttr("checked");
                    }
                    selfObj.saveState($(input).attr('value'));
                });

            });
        }

    }
    /**
     *
     * @returns {Boolean}
     */
    this.bindEvents = function () {
        selfObj.isAnySearch();
        $('input[name="mediaType[]"]').click(function () {
            checkParentFacet('media_type', $(this).prop("checked"));
        });
        $('input[name="commercial[]"]').click(function () {
            checkParentFacet('commercial', $(this).prop('checked'));
        });
        $('input[name="format[]"]').click(function () {
            checkParentFacet('format', $(this).prop('checked'));
        });
        $('input[name="base[]"]').click(function () {
            checkParentFacet('base', $(this).prop('checked'));
        });
        $('input[name="recordingStandard[]"]').click(function () {
            checkParentFacet('recordingStandard', $(this).prop('checked'));
        });
        $('input[name="printType[]"]').click(function () {
            checkParentFacet('printType', $(this).prop('checked'));
        });
        $('input[name="project[]"]').click(function () {
            checkParentFacet('project', $(this).prop('checked'));
        });
        $('input[name="reelDiameter[]"]').click(function () {
            checkParentFacet('reelDiameter', $(this).prop('checked'));
        });
        $('input[name="discDiameter[]"]').click(function () {
            checkParentFacet('discDiameter', $(this).prop('checked'));
        });
        $('input[name="acidDetection[]"]').click(function () {
            checkParentFacet('acidDetection', $(this).prop('checked'));
        });
        $('input[name="collectionName[]"]').click(function () {
            checkParentFacet('collectionName', $(this).prop('checked'));
        });
        initTriStateCheckBox('is_review_check', 'is_review_check_state', true);
        $('#is_review_check').click(function () {
            var totalChecked = $('#total_checked').val();
            var containerId = $(this).attr('id');
            var currentVal = $('#' + containerId + '_state').val();
            if (currentVal > 0 && totalChecked == 0)
            {
                totalChecked++;
                $('#parent_facet').val(containerId);
                $('#total_checked').val(totalChecked);
            }
            if (currentVal == 0 && $('#parent_facet').val() == containerId) {
                totalChecked--;
                $('#parent_facet').val('');
                $('#total_checked').val(totalChecked);
            }
            filterRecords();
        });
        $('#reset_all').click(function () {
            selfObj.resetAll();
        });

        selfObj.addCustomToken();
        $('#addKeyword').click(function () {
            selfObj.addKeyword();
        });
        $('#keywordSearch').keypress(function (e) {
            if (e.which == 13) {
                selfObj.addKeyword();
            }
        });

        selfObj.removeFilter();
        selfObj.removeKeywordFilter();
        return true;
    }
    /**
     *
     * @param {type} type
     * @param {type} isChecked
     * @returns {undefined}
     */
    var checkParentFacet = function (type, isChecked) {
        //todo need to update function
        var totalChecked = $('#total_checked').val();
        var total = $('#facet_sidebar input:checked').length;
        if (total == 0)
            totalChecked = 0;
        if (isChecked)
            totalChecked++;
        else
            totalChecked--;
        if (totalChecked < 0)
            totalChecked = 0;
        $('#total_checked').val(totalChecked);

        if ($('#parent_facet').val() == '' && totalChecked == 1)
            $('#parent_facet').val(type);
        else if (totalChecked == 0)
            $('#parent_facet').val('');
        filterRecords();
    }
    /**
     *
     * @returns {undefined}
     */
    var filterRecords = function () {
        $.blockUI({
            message: 'Please wait...',
            css: {
                border: 'none',
                padding: '15px',
                backgroundColor: '#000',
                '-webkit-border-radius': '10px',
                '-moz-border-radius': '10px',
                opacity: .5,
                color: '#fff',
                zIndex: 999999
            }
        });
        $.ajax({
            type: 'GET',
            url: pageUrl,
            data: $('#formSearch').serialize(),
            dataType: 'json',
            success: function (response)
            {
                $("#recordsContainer").html(response.html);
                var source = $('#metro-js').attr('src');
                var script = document.createElement("script");
                script.type = "text/javascript";
                script.src = source;
                script.id = "metro-js";
                $("#recordsContainer").append(script);
                selfObj.initDataTable();
                selfObj.bindEvents();
                $('body').scrollTop(0);
                $.unblockUI();
            }

        });
    }

    /**
     *
     * @returns {undefined}
     */
    this.addCustomToken = function () {
        $('.customToken').click(function () {
            customFieldName = $(this).attr('data-fieldName');
            customColumnName = $(this).attr('data-columnName');
            $('#limit_field_text').html(customFieldName);
        });
    }

    this.addKeyword = function () {
        if ($('#keywordSearch').val() != '') {
            if ($('#facet_keyword_search').val() != '' && $('#facet_keyword_search').val() != '""') {
                Filters = JSON.parse($('#facet_keyword_search').val());
            }
            else {
                Filters = new Array();
            }
            for (x in Filters) {
                if (Filters[x].value == $('#keywordSearch').val()) {
                    alert($('#keywordSearch').val() + " filter is already applied.");
                    return false;
                }
            }
            var temp = {};
            temp.value = $('#keywordSearch').val();
            temp.type = customColumnName;
            Filters.push(temp);

            $('#facet_keyword_search').val(JSON.stringify(Filters));
            customFieldName = 'All';
            customColumnName = 'all';
            filterRecords();
        }
    }

    this.removeFilter = function () {
        $('.delFilter').click(function () {
            elementID = $(this).attr('data-elementId');
            type = $(this).attr('data-type');
            $('#' + elementID).prop('checked', false);
            checkParentFacet(type);
        });
    }
    this.removeKeywordFilter = function () {
        $('.deleteKeyword').click(function () {
            var index = $.trim($(this).data().index);
            Filters = JSON.parse($('#facet_keyword_search').val());
            delete (Filters[index]);
            Filters.splice(index, 1);
            $('#facet_keyword_search').val(JSON.stringify(Filters));
            filterRecords();
        });

    }
    this.resetAll = function () {
        $('#formSearch').find('input:hidden, input:text, select').val('');
        $('#formSearch').find('input:radio, input:checkbox')
                .removeAttr('checked').removeAttr('selected');
        filterRecords();
    }
    this.isAnySearch = function () {
        if ($('.search_keys').length > 0) {
            $('#reset_all').show();
        }
        else {
            $('#reset_all').hide();

        }

    }
    this.selectAllRecords = function () {
        $('#selectAll').click(function () {
            if($(this).prop('checked') == true){
                selectAllRecords = true;
               $('input[name=record_checkbox]').attr('checked', 'checked');
            }else if($(this).prop('checked') == false){
                selectAllRecords = false;
               $('input[name=record_checkbox]').removeAttr('checked');
            }
            selfObj.saveState(0, '', 1);
        });
    }

    this.saveState = function (elementID, select, isChecked) {
        var id = '';
        var checked = 0;
        var isAll = 0;
        if (select) {
            if (select == 'all') {
                checked = isChecked;
                isAll = 1;
            }
            else {
                checked = isChecked;
                $('input[name=record_checkbox]').each(function () {
                    id += $(this).val() + ',';
                });
            }
        }
        else {
            id = elementID;
            if ($('#row_' + elementID).attr('checked'))
                checked = 1;
        }

        $.ajax({
            type: 'POST',
            url: ajaxSaveStateUrl,
            data: {id: id, checked: checked, is_all: isAll, },
            dataType: 'json',
            success: function (response)
            {

            }
        });
    }
}

<commit_msg>records selections<commit_after>/**
 * Class of managing Filtering and displaying of records.
 *
 * @returns {Records}
 */
function Records() {
    /**
     * Object of datatable.
     */
//	this.oTable = null;
    /**
     * URL for managing calls of datatable
     * @type {string}
     */
    var ajaxSource = null;
    var pageUrl = null;
    var selfObj = this;
    var Filters = new Object();
    var customFieldName = 'All';
    var customColumnName = 'all';
    var ajaxSaveStateUrl = null;
    var selectAllRecords = false;
    /**
     * Set the ajax URL of datatable.
     * @param {string} source
     *
     */
    this.setAjaxSource = function (source) {
        ajaxSource = source;

    }
    /**
     * Set the ajax URL for selected rows of datatable.
     * @param {string} source
     *
     */
    this.setAjaxSaveStateUrl = function (source) {
        ajaxSaveStateUrl = source;

    }
    /**
     * Set the page url.
     * @param {string} url
     *
     */
    this.setPageUrl = function (url) {
        pageUrl = url;

    }
    /**
     * Initialize the datatable.
     *
     */
    this.initDataTable = function () {
        // check the existence of table on which we are going to apply datatable.
        if ($('#records').length > 0)
        {
            // Modify css for managing view.
//			$('#container').removeClass('container');
//			$('#container').css('margin', '20px');
            var selected = [];
            oTable =
                    $('#records').dataTable(
                    {
                        "dom": '<"top"p><"clear">tir<"bottom"p>',
                        "bProcessing": true,
                        "bServerSide": true,
                        retrieve: true,
                        destroy: true,
                        "language": {
                            "info": "Showing _START_ - _END_ of _MAX_",
                            "infoFiltered": ''
                        },
                        "aoColumnDefs": [
                            {"bSortable": false, "aTargets": [0]}
                        ],
                        "aaSorting": [],
                        "sAjaxSource": ajaxSource,
                        "bStateSave": true,
//				"fnInitComplete": function () {
//					this.oTable.fnAdjustColumnSizing();
//				},
                        "fnServerData": function (sSource, aoData, fnCallback) {
                            jQuery.getJSON(sSource, aoData, function (json) {
                                fnCallback(json);
                            });
                        },
                        "createdRow": function (row, data, index) {
                            var input = $(row).find("td:first").html();
                            row.id = "row-" + $(input).attr('value');
                        },
                        "ajax": ajaxSaveStateUrl,
                        "rowCallback": function (row, data) {
                            if ($.inArray(row.id, selected) !== -1) {
                                $(row).addClass('selected');
                                $(selected).each(function (key, value) {
                                    var input = $("#" + value + " td:first").html();
                                    $("#" + $(input).attr('id')).attr("checked", "checked");
                                    $("#" + $(input).attr('id')).prop("checked", true);
                                });
                            }
                        }
                    });
            $('#records tbody').on('click', 'tr', function () {
                var id = this.id;
                var index = $.inArray(id, selected);
                if (index === -1) {
                    selected.push(id);
                } else {
                    selected.splice(index, 1);
                }
                $(this).toggleClass('selected', function () {
                    var input = $("#" + id + " td:first").html();
                    if ($(this).hasClass('selected') === true) {
                        $("#" + $(input).attr('id')).attr("checked", "checked");
                        $("#" + $(input).attr('id')).prop("checked", true);
                    } else {
                        $("#" + $(input).attr('id')).removeAttr("checked");
                    }
                    selfObj.saveState($(input).attr('value'));
                });

            });
        }

    }
    /**
     *
     * @returns {Boolean}
     */
    this.bindEvents = function () {
        selfObj.isAnySearch();
        $('input[name="mediaType[]"]').click(function () {
            checkParentFacet('media_type', $(this).prop("checked"));
        });
        $('input[name="commercial[]"]').click(function () {
            checkParentFacet('commercial', $(this).prop('checked'));
        });
        $('input[name="format[]"]').click(function () {
            checkParentFacet('format', $(this).prop('checked'));
        });
        $('input[name="base[]"]').click(function () {
            checkParentFacet('base', $(this).prop('checked'));
        });
        $('input[name="recordingStandard[]"]').click(function () {
            checkParentFacet('recordingStandard', $(this).prop('checked'));
        });
        $('input[name="printType[]"]').click(function () {
            checkParentFacet('printType', $(this).prop('checked'));
        });
        $('input[name="project[]"]').click(function () {
            checkParentFacet('project', $(this).prop('checked'));
        });
        $('input[name="reelDiameter[]"]').click(function () {
            checkParentFacet('reelDiameter', $(this).prop('checked'));
        });
        $('input[name="discDiameter[]"]').click(function () {
            checkParentFacet('discDiameter', $(this).prop('checked'));
        });
        $('input[name="acidDetection[]"]').click(function () {
            checkParentFacet('acidDetection', $(this).prop('checked'));
        });
        $('input[name="collectionName[]"]').click(function () {
            checkParentFacet('collectionName', $(this).prop('checked'));
        });
        initTriStateCheckBox('is_review_check', 'is_review_check_state', true);
        $('#is_review_check').click(function () {
            var totalChecked = $('#total_checked').val();
            var containerId = $(this).attr('id');
            var currentVal = $('#' + containerId + '_state').val();
            if (currentVal > 0 && totalChecked == 0)
            {
                totalChecked++;
                $('#parent_facet').val(containerId);
                $('#total_checked').val(totalChecked);
            }
            if (currentVal == 0 && $('#parent_facet').val() == containerId) {
                totalChecked--;
                $('#parent_facet').val('');
                $('#total_checked').val(totalChecked);
            }
            filterRecords();
        });
        $('#reset_all').click(function () {
            selfObj.resetAll();
        });

        selfObj.addCustomToken();
        $('#addKeyword').click(function () {
            selfObj.addKeyword();
        });
        $('#keywordSearch').keypress(function (e) {
            if (e.which == 13) {
                selfObj.addKeyword();
            }
        });

        selfObj.removeFilter();
        selfObj.removeKeywordFilter();
        return true;
    }
    /**
     *
     * @param {type} type
     * @param {type} isChecked
     * @returns {undefined}
     */
    var checkParentFacet = function (type, isChecked) {
        //todo need to update function
        var totalChecked = $('#total_checked').val();
        var total = $('#facet_sidebar input:checked').length;
        if (total == 0)
            totalChecked = 0;
        if (isChecked)
            totalChecked++;
        else
            totalChecked--;
        if (totalChecked < 0)
            totalChecked = 0;
        $('#total_checked').val(totalChecked);

        if ($('#parent_facet').val() == '' && totalChecked == 1)
            $('#parent_facet').val(type);
        else if (totalChecked == 0)
            $('#parent_facet').val('');
        filterRecords();
    }
    /**
     *
     * @returns {undefined}
     */
    var filterRecords = function () {
        $.blockUI({
            message: 'Please wait...',
            css: {
                border: 'none',
                padding: '15px',
                backgroundColor: '#000',
                '-webkit-border-radius': '10px',
                '-moz-border-radius': '10px',
                opacity: .5,
                color: '#fff',
                zIndex: 999999
            }
        });
        $.ajax({
            type: 'GET',
            url: pageUrl,
            data: $('#formSearch').serialize(),
            dataType: 'json',
            success: function (response)
            {
                $("#recordsContainer").html(response.html);
                var source = $('#metro-js').attr('src');
                var script = document.createElement("script");
                script.type = "text/javascript";
                script.src = source;
                script.id = "metro-js";
                $("#recordsContainer").append(script);
                selfObj.initDataTable();
                selfObj.bindEvents();
                $('body').scrollTop(0);
                $.unblockUI();
            }

        });
    }

    /**
     *
     * @returns {undefined}
     */
    this.addCustomToken = function () {
        $('.customToken').click(function () {
            customFieldName = $(this).attr('data-fieldName');
            customColumnName = $(this).attr('data-columnName');
            $('#limit_field_text').html(customFieldName);
        });
    }

    this.addKeyword = function () {
        if ($('#keywordSearch').val() != '') {
            if ($('#facet_keyword_search').val() != '' && $('#facet_keyword_search').val() != '""') {
                Filters = JSON.parse($('#facet_keyword_search').val());
            }
            else {
                Filters = new Array();
            }
            for (x in Filters) {
                if (Filters[x].value == $('#keywordSearch').val()) {
                    alert($('#keywordSearch').val() + " filter is already applied.");
                    return false;
                }
            }
            var temp = {};
            temp.value = $('#keywordSearch').val();
            temp.type = customColumnName;
            Filters.push(temp);

            $('#facet_keyword_search').val(JSON.stringify(Filters));
            customFieldName = 'All';
            customColumnName = 'all';
            filterRecords();
        }
    }

    this.removeFilter = function () {
        $('.delFilter').click(function () {
            elementID = $(this).attr('data-elementId');
            type = $(this).attr('data-type');
            $('#' + elementID).prop('checked', false);
            checkParentFacet(type);
        });
    }
    this.removeKeywordFilter = function () {
        $('.deleteKeyword').click(function () {
            var index = $.trim($(this).data().index);
            Filters = JSON.parse($('#facet_keyword_search').val());
            delete (Filters[index]);
            Filters.splice(index, 1);
            $('#facet_keyword_search').val(JSON.stringify(Filters));
            filterRecords();
        });

    }
    this.resetAll = function () {
        $('#formSearch').find('input:hidden, input:text, select').val('');
        $('#formSearch').find('input:radio, input:checkbox')
                .removeAttr('checked').removeAttr('selected');
        filterRecords();
    }
    this.isAnySearch = function () {
        if ($('.search_keys').length > 0) {
            $('#reset_all').show();
        }
        else {
            $('#reset_all').hide();

        }

    }
    this.selectAllRecords = function () {
        $('#selectAll').click(function () {
            if($(this).prop('checked') == true){
                selectAllRecords = true;
               $('input[name=record_checkbox]').attr('checked', 'checked');
               $('input[name=record_checkbox]').prop('checked',true);
            }else if($(this).prop('checked') == false){
                selectAllRecords = false;
               $('input[name=record_checkbox]').removeAttr('checked');
               $('input[name=record_checkbox]').prop('checked',false);
            }
            selfObj.saveState(0, '', 1);
        });
    }

    this.saveState = function (elementID, select, isChecked) {
        var id = '';
        var checked = 0;
        var isAll = 0;
        if (select) {
            if (select == 'all') {
                checked = isChecked;
                isAll = 1;
            }
            else {
                checked = isChecked;
                $('input[name=record_checkbox]').each(function () {
                    id += $(this).val() + ',';
                });
            }
        }
        else {
            id = elementID;
            if ($('#row_' + elementID).attr('checked'))
                checked = 1;
        }

        $.ajax({
            type: 'POST',
            url: ajaxSaveStateUrl,
            data: {id: id, checked: checked, is_all: isAll, },
            dataType: 'json',
            success: function (response)
            {

            }
        });
    }
}

<|endoftext|>


<commit_before>/**
 * Class of managing Filtering and displaying of records.
 *
 * @returns {Records}
 */
function Records() {
    /**
     * Object of datatable.
     */
//	this.oTable = null;
    /**
     * URL for managing calls of datatable
     * @type {string}
     */
    var ajaxSource = null;
    var pageUrl = null;
    var selfObj = this;
    /**
     * Set the ajax URL of datatable.
     * @param {string} source
     *
     */
    this.setAjaxSource = function (source) {
        ajaxSource = source;

    }
    /**
     * Set the page url.
     * @param {string} url
     *
     */
    this.setPageUrl = function (url) {
        pageUrl = url;

    }
    /**
     * Initialize the datatable.
     *
     */
    this.initDataTable = function () {
        // check the existence of table on which we are going to apply datatable.
        if ($('#records').length > 0)
        {
            // Modify css for managing view.
            $('#container').removeClass('container');
            $('#container').css('margin', '20px');
            oTable =
                    $('#records').dataTable(
                    {
                        "dom": '<"top"p><"clear">tir<"bottom"p>',
                        "bProcessing": true,
                        "bServerSide": true,
                        retrieve: true,
                        destroy: true,
                        "language": {
                            "info": "Showing _START_ - _END_ of _MAX_",
                            "infoFiltered": ''
                        },
                        "aoColumnDefs": [
                            {"bSortable": false, "aTargets": [0]}
                        ],
                        "aaSorting": [],
                        "sAjaxSource": ajaxSource,
                        "bStateSave": true,
//				"fnInitComplete": function () {
//					this.oTable.fnAdjustColumnSizing();
//				},
                        "fnServerData": function (sSource, aoData, fnCallback) {
                            jQuery.getJSON(sSource, aoData, function (json) {
                                fnCallback(json);

                            });
                        },
                    });
        }

    }
    /**
     *
     * @returns {Boolean}
     */
    this.bindEvents = function () {
        $('input[name="mediaType[]"]').click(function () {
            checkParentFacet('media_type', $(this).attr('checked'));
        });
        $('input[name="commercial[]"]').click(function () {
            checkParentFacet('commercial', $(this).attr('checked'));
        });
        $('input[name="format[]"]').click(function () {
            checkParentFacet('format', $(this).attr('checked'));
        });
        $('input[name="base[]"]').click(function () {
            checkParentFacet('base', $(this).attr('checked'));
        });
        $('input[name="recordingStandard[]"]').click(function () {
            checkParentFacet('recordingStandard', $(this).attr('checked'));
        });
        $('input[name="printType[]"]').click(function () {
            checkParentFacet('printType', $(this).attr('checked'));
        });
        $('input[name="project[]"]').click(function () {
            checkParentFacet('project', $(this).attr('checked'));
        });
        $('input[name="reelDiameter[]"]').click(function () {
            checkParentFacet('reelDiameter', $(this).attr('checked'));
        });
        $('input[name="discDiameter[]"]').click(function () {
            checkParentFacet('discDiameter', $(this).attr('checked'));
        });
        $('input[name="acidDetection[]"]').click(function () {
            checkParentFacet('acidDetection', $(this).attr('checked'));
        });

        return true;
    }
    /**
     *
     * @param {type} type
     * @param {type} isChecked
     * @returns {undefined}
     */
    var checkParentFacet = function (type, isChecked) {
        //todo need to update function
        var totalChecked = $('#total_checked').val();
        var total = $('#facet_sidebar input:checked').length;
        if (total == 0)
            totalChecked = 0;
        if (isChecked == 'checked')
            totalChecked++;
        else
            totalChecked--;

        $('#total_checked').val(totalChecked);

        if ($('#parent_facet').val() == '' && totalChecked == 1)
            $('#parent_facet').val(type);
        else if (totalChecked == 0)
            $('#parent_facet').val('');
        filterRecords();
    }
    /**
     *
     * @returns {undefined}
     */
    var filterRecords = function () {
        $.ajax({
            type: 'POST',
            url: pageUrl,
            data: $('#formSearch').serialize(),
            dataType: 'json',
            success: function (response)
            {
                selfObj.initDataTable();
//                window.location.reload();
            }

        });

    }
}

<commit_msg>facets<commit_after>/**
 * Class of managing Filtering and displaying of records.
 *
 * @returns {Records}
 */
function Records() {
    /**
     * Object of datatable.
     */
//	this.oTable = null;
    /**
     * URL for managing calls of datatable
     * @type {string}
     */
    var ajaxSource = null;
    var pageUrl = null;
    var selfObj = this;
    /**
     * Set the ajax URL of datatable.
     * @param {string} source
     *
     */
    this.setAjaxSource = function (source) {
        ajaxSource = source;

    }
    /**
     * Set the page url.
     * @param {string} url
     *
     */
    this.setPageUrl = function (url) {
        pageUrl = url;

    }
    /**
     * Initialize the datatable.
     *
     */
    this.initDataTable = function () {
        // check the existence of table on which we are going to apply datatable.
        if ($('#records').length > 0)
        {
            // Modify css for managing view.
            $('#container').removeClass('container');
            $('#container').css('margin', '20px');
            oTable =
                    $('#records').dataTable(
                    {
                        "dom": '<"top"p><"clear">tir<"bottom"p>',
                        "bProcessing": true,
                        "bServerSide": true,
                        retrieve: true,
                        destroy: true,
                        "language": {
                            "info": "Showing _START_ - _END_ of _MAX_",
                            "infoFiltered": ''
                        },
                        "aoColumnDefs": [
                            {"bSortable": false, "aTargets": [0]}
                        ],
                        "aaSorting": [],
                        "sAjaxSource": ajaxSource,
                        "bStateSave": true,
//				"fnInitComplete": function () {
//					this.oTable.fnAdjustColumnSizing();
//				},
                        "fnServerData": function (sSource, aoData, fnCallback) {
                            jQuery.getJSON(sSource, aoData, function (json) {
                                fnCallback(json);

                            });
                        },
                    });
        }

    }
    /**
     *
     * @returns {Boolean}
     */
    this.bindEvents = function () {
        $('input[name="mediaType[]"]').click(function () {
            checkParentFacet('media_type', $(this).attr('checked'));
        });
        $('input[name="commercial[]"]').click(function () {
            checkParentFacet('commercial', $(this).attr('checked'));
        });
        $('input[name="format[]"]').click(function () {
            checkParentFacet('format', $(this).attr('checked'));
        });
        $('input[name="base[]"]').click(function () {
            checkParentFacet('base', $(this).attr('checked'));
        });
        $('input[name="recordingStandard[]"]').click(function () {
            checkParentFacet('recordingStandard', $(this).attr('checked'));
        });
        $('input[name="printType[]"]').click(function () {
            checkParentFacet('printType', $(this).attr('checked'));
        });
        $('input[name="project[]"]').click(function () {
            checkParentFacet('project', $(this).attr('checked'));
        });
        $('input[name="reelDiameter[]"]').click(function () {
            checkParentFacet('reelDiameter', $(this).attr('checked'));
        });
        $('input[name="discDiameter[]"]').click(function () {
            checkParentFacet('discDiameter', $(this).attr('checked'));
        });
        $('input[name="acidDetection[]"]').click(function () {
            checkParentFacet('acidDetection', $(this).attr('checked'));
        });

        return true;
    }
    /**
     *
     * @param {type} type
     * @param {type} isChecked
     * @returns {undefined}
     */
    var checkParentFacet = function (type, isChecked) {
        //todo need to update function
        var totalChecked = $('#total_checked').val();
        var total = $('#facet_sidebar input:checked').length;
        if (total == 0)
            totalChecked = 0;
        if (isChecked == 'checked')
            totalChecked++;
        else
            totalChecked--;

        $('#total_checked').val(totalChecked);

        if ($('#parent_facet').val() == '' && totalChecked == 1)
            $('#parent_facet').val(type);
        else if (totalChecked == 0)
            $('#parent_facet').val('');
        filterRecords();
    }
    /**
     *
     * @returns {undefined}
     */
    var filterRecords = function () {
        $.ajax({
            type: 'POST',
            url: pageUrl,
            data: $('#formSearch').serialize(),
            dataType: 'json',
            success: function (response)
            {
                selfObj.initDataTable();
                window.location.reload();
            }

        });

    }
}

<|endoftext|>


<commit_before>var fileName = __filename.slice(__dirname.length + 1),
    commands = [],
    charSheets = require("./storage/" + fileName + "/charsheets.json"),
    fs = require("fs");

var CharSheet = function() {
    //core
    this.name = "";
    this.lv = 1;

    //details
    this.alignment = "";
    this.race = "";
    this.gender = "";
    this.hair = "";
    this.eyes = "";
    this.age = "0";
    this.height = "0";
    this.weight = "0";

    //stats
    this.str = 1;
    this.per = 1;
    this.dex = 1;
    this.con = 1;
    this.int = 1;
    this.wis = 1;
    this.cha = 1;
};

/*
    Prints out the character sheet for the sender

    id: id of sender
*/
function printSheet(id) {
    if (!charSheets[id]) {
        console.log("no such sheet for id " + id);
        return null;
    }
    var outputString = "";
    for (var stat in charSheets[id]) {
        outputString = outputString + stat + ": " + charSheets[id][stat] + "\n";
    }
    return outputString;
}

/*
    Saves the current charSheets to a file
*/
function writeToSheet() {
    // writes the current charSheets to ./scripts/storage/tabletop.js/charsheets.json for permanent storage
    fs.writeFile("./scripts/storage/" + fileName + "/charsheets.json", JSON.stringify(charSheets, null, 4), function (err) {
        if (err) {
            console.log(err);
            process.exit(-1);
        }
        console.log("Wrote contents of charSheets to charsheets.json");
    });
}

/*
    Change the stats of an existing or new character sheet

    message: message that prompted the change
*/
function updateCharSheet(message) {
    var words = message.content.split(" "),
        newSheet;

    // get the user's sheet if it exists, otherwise create a new one
    if (charSheets[message.author.id]) {
        newSheet = charSheets[message.author.id];
    } else {
        newSheet = new CharSheet();
    }

    words.splice(0, 1); // remove the command, leaving only arguments
    words = words.join(" ");

    // delete the sheet if the user chooses
    if (words === "DELETETHISSHEET") {
        return "TOBEDELETED";
    }

    // split the stat changes, delimited by " & "
    words = words.split(" & ");

    //for every stat change the user passed
    for (var argument in words) {
        // get the argument text
        argument = words[argument];

        // check argument format to see if it matches one of the following operations
        var operation;
        if (argument.match(/^([A-z])+\=+([\-\w\ ])+/g) !== null) { // ex. str=30
            operation = "=";
        } else if (argument.match(/^([A-z])+\++([\-0-9])+/g) !== null) { // ex. str+30
            operation = "+";
        } else if (argument.match(/^([A-z])+\-+([\-0-9])+/g) !== null) { // ex. str-30
            operation = "-";
        } else {
            // otherwise, return with error
            console.log("no match found");
            return null;
        }

        // check if the stat being changed exists
        var subArgs = argument.split(operation);
        if (typeof newSheet[subArgs[0]] === "undefined") {
            // otherwise, return with error
            console.log("no stat found");
            return null;
        }

        // parse the change as a number, will be checked for success later
        var numericalChange = parseInt(subArgs[1]);

        switch (operation) {
            case "=":
                // if both the change and the stat being changed are numbers
                if (numericalChange !== null && typeof newSheet[subArgs[0]] === "number") {
                    newSheet[subArgs[0]] = numericalChange;
                } else if (typeof newSheet[subArgs[0]] === typeof subArgs[1]) { // if not, check if the types match at all
                    newSheet[subArgs[0]] = subArgs[1];
                } else { // otherwise, return with error
                    console.log("tried to change type for stat " + subArgs[0]);
                    return null;
                }
                break;
            case "-":
                // you get the idea
                if (isNaN(numericalChange)) return null;
                newSheet[subArgs[0]] -= numericalChange; // adjust by numericalChange if it exists
                break;
            case "+":
                if (isNaN(numericalChange)) return null;
                newSheet[subArgs[0]] += numericalChange; // likewise
                break;
            default:
                return null;
        }
    }

    return newSheet;
}

//unfinished
function getSkill(skill, playerSheet) {
    skill = skill.toLowerCase();
    switch (skill) {
        case "speech":

            break;
        case "barter":

            break;
        case "performing":

            break;
        case "lock-Picking":

            break;
        case "archery":

            break;
        case "one-handed":

            break;
        case "bwo-handed":

            break;
        case "block":

            break;
        case "intimidate":

            break;
        case "parry":

            break;
        case "acrobatics":

            break;
        case "stealth":

            break;
        case "knowledge (survival)":
        case "survival":

            break;
        case "knowledge (medicine)":
        case "medicine":

            break;
        case "knowledge (scholarly)":
        case "scholarly":

            break;
        case "alchemy":

            break;
        case "magic (healing)":
        case "healing":

            break;
        case "magic (offensive)":
        case "offensive":

            break;
        case "magic (defensive)":
        case "defensive":

            break;
        case "magic (summoning)":
        case "summoning":

            break;
        case "magic (illusions)":
        case "illusions":

            break;
        default:
            //things
            break;
    }
}

module.exports = function(bot) {
    return {
        commands: commands,
        dice: function(message) {
            var words = message.content.split(" "),
                total = 0;
            // check to see if the message word count is valid
            if (words.length === 2 && words[1] === "?") {
                bot.sendMessage(message.channel, "Description: Rolls virtual dice and displays output in channel.\nSyntax: !dice ``num of dice``d``max dice value``+``bonus``");
                return;
            } else if (words.length !== 2) {
                poorSyntax("!dice", message);
                return;
            }

            // check to see if the dice parameter given is correctly formatted
            // example of proper input is 1d20+5
            if (words[1].match(/[0-9]+d[0-9]+\+[0-9]+/g)) {
                var numbers = [];
                total = 0;

                // parse all of the 3 fields as number (0. number of dice, 1. max value, 2. bonus)
                for (var i = 0; i < 3; i++) {
                    numbers[i] = parseInt(words[1].match(/[0-9]+/g)[i]);
                }

                // roll numbers[0] dice
                for (var j = 0; j < numbers[0]; j++) {
                    total += Math.ceil(Math.random() * numbers[1]);
                }

                // add bonus, send final message
                total += numbers[2];
                bot.sendMessage(message.channel, "You rolled a " + Math.ceil(total));
            } else {
                bot.sendMessage(message.channel, "Invalid dice given. Input is formatted ``num of dice``d``max dice value``+``bonus``");
            }
            return;
        },
        changesheet: function(message) {
            var newSheet = updateCharSheet(message);
            if (newSheet === null) {
                poorSyntax("!sheet", message);
                return;
            } else if (newSheet === "TOBEDELETED") {
                charSheets[message.author.id] = undefined;
            } else {
                charSheets[message.author.id] = newSheet;
            }
            //dangerous -- remove below after functions finished
            writeToSheet();
            return;
        },
        printsheet: function(message) {
            var outputString = printSheet(message.author.id);
            if (!outputString) {
                poorSyntax("!mysheet", message);
                return;
            } else {
                bot.sendMessage(message.channel, outputString);
            }
            return;
        }
    };
};<commit_msg>diceydice<commit_after>var fileName = __filename.slice(__dirname.length + 1),
    commands = [],
    charSheets = require("./storage/" + fileName + "/charsheets.json"),
    fs = require("fs");

var CharSheet = function() {
    //core
    this.name = "";
    this.lv = 1;

    //details
    this.alignment = "";
    this.race = "";
    this.gender = "";
    this.hair = "";
    this.eyes = "";
    this.age = "0";
    this.height = "0";
    this.weight = "0";

    //stats
    this.str = 1;
    this.per = 1;
    this.dex = 1;
    this.con = 1;
    this.int = 1;
    this.wis = 1;
    this.cha = 1;
};

/*
    Prints out the character sheet for the sender

    id: id of sender
*/
function printSheet(id) {
    if (!charSheets[id]) {
        console.log("no such sheet for id " + id);
        return null;
    }
    var outputString = "";
    for (var stat in charSheets[id]) {
        outputString = outputString + stat + ": " + charSheets[id][stat] + "\n";
    }
    return outputString;
}

/*
    Saves the current charSheets to a file
*/
function writeToSheet() {
    // writes the current charSheets to ./scripts/storage/tabletop.js/charsheets.json for permanent storage
    fs.writeFile("./scripts/storage/" + fileName + "/charsheets.json", JSON.stringify(charSheets, null, 4), function (err) {
        if (err) {
            console.log(err);
            process.exit(-1);
        }
        console.log("Wrote contents of charSheets to charsheets.json");
    });
}

/*
    Change the stats of an existing or new character sheet

    message: message that prompted the change
*/
function updateCharSheet(message) {
    var words = message.content.split(" "),
        newSheet;

    // get the user's sheet if it exists, otherwise create a new one
    if (charSheets[message.author.id]) {
        newSheet = charSheets[message.author.id];
    } else {
        newSheet = new CharSheet();
    }

    words.splice(0, 1); // remove the command, leaving only arguments
    words = words.join(" ");

    // delete the sheet if the user chooses
    if (words === "DELETETHISSHEET") {
        return "TOBEDELETED";
    }

    // split the stat changes, delimited by " & "
    words = words.split(" & ");

    //for every stat change the user passed
    for (var argument in words) {
        // get the argument text
        argument = words[argument];

        // check argument format to see if it matches one of the following operations
        var operation;
        if (argument.match(/^([A-z])+\=+([\-\w\ ])+/g) !== null) { // ex. str=30
            operation = "=";
        } else if (argument.match(/^([A-z])+\++([\-0-9])+/g) !== null) { // ex. str+30
            operation = "+";
        } else if (argument.match(/^([A-z])+\-+([\-0-9])+/g) !== null) { // ex. str-30
            operation = "-";
        } else {
            // otherwise, return with error
            console.log("no match found");
            return null;
        }

        // check if the stat being changed exists
        var subArgs = argument.split(operation);
        if (typeof newSheet[subArgs[0]] === "undefined") {
            // otherwise, return with error
            console.log("no stat found");
            return null;
        }

        // parse the change as a number, will be checked for success later
        var numericalChange = parseInt(subArgs[1]);

        switch (operation) {
            case "=":
                // if both the change and the stat being changed are numbers
                if (numericalChange !== null && typeof newSheet[subArgs[0]] === "number") {
                    newSheet[subArgs[0]] = numericalChange;
                } else if (typeof newSheet[subArgs[0]] === typeof subArgs[1]) { // if not, check if the types match at all
                    newSheet[subArgs[0]] = subArgs[1];
                } else { // otherwise, return with error
                    console.log("tried to change type for stat " + subArgs[0]);
                    return null;
                }
                break;
            case "-":
                // you get the idea
                if (isNaN(numericalChange)) return null;
                newSheet[subArgs[0]] -= numericalChange; // adjust by numericalChange if it exists
                break;
            case "+":
                if (isNaN(numericalChange)) return null;
                newSheet[subArgs[0]] += numericalChange; // likewise
                break;
            default:
                return null;
        }
    }

    return newSheet;
}

//unfinished
function getSkill(skill, playerSheet) {
    skill = skill.toLowerCase();
    switch (skill) {
        case "speech":

            break;
        case "barter":

            break;
        case "performing":

            break;
        case "lock-Picking":

            break;
        case "archery":

            break;
        case "one-handed":

            break;
        case "bwo-handed":

            break;
        case "block":

            break;
        case "intimidate":

            break;
        case "parry":

            break;
        case "acrobatics":

            break;
        case "stealth":

            break;
        case "knowledge (survival)":
        case "survival":

            break;
        case "knowledge (medicine)":
        case "medicine":

            break;
        case "knowledge (scholarly)":
        case "scholarly":

            break;
        case "alchemy":

            break;
        case "magic (healing)":
        case "healing":

            break;
        case "magic (offensive)":
        case "offensive":

            break;
        case "magic (defensive)":
        case "defensive":

            break;
        case "magic (summoning)":
        case "summoning":

            break;
        case "magic (illusions)":
        case "illusions":

            break;
        default:
            //things
            break;
    }
}

module.exports = function(bot) {
    return {
        commands: commands,
        dice: function(message) {
            var words = message.content.split(" "),
                total = 0;
            var descMessage = "Description: Rolls virtual dice and displays output in channel.\nSyntax: !dice ``num of dice``d``max dice value``+``bonus``";
            var invalidMessage = "Invalid dice given. Input is formatted ``num of dice``d``max dice value``+``bonus``";
            // check to see if the message word count is valid
            if (words.length === 2 && words[1] === "?") {
                bot.sendMessage(message.channel, descMessage);
                return;
            } else if (words.length !== 2) {
                poorSyntax("!dice", message);
                return;
            }
            // check to see if the dice parameter given is correctly formatted
            // example of proper input is 1d20+5
            var pat = /([0-9]+)d([0-9]+)\+([0-9]+)/g;
            var tokens = pat.exec(words[1]); //tokenizing pattern on words
            if (tokens === null) bot.sendMessage(message.channel, invalidMessage); //send invalid if null
            else {
                var numbers = tokens.slice(1,4); //slicing middle tokens out for numbers
                for (var i in numbers) numbers[i] = parseInt(numbers[i]); //parsing to numbers
                for (var j = 0; j < numbers[0]; j++) { //rolling dice number of times
                    total += Math.ceil(Math.random() * numbers[1]);
                }
                total += numbers[2]; //adding bonus
                bot.sendMessage(message.channel, "You rolled a " + Math.ceil(total)); //passing result message to channel
            }

            // if (words[1].match(/[0-9]+d[0-9]+\+[0-9]+/g)) {
            //     var numbers = [];
            //     total = 0;

            //     // parse all of the 3 fields as number (0. number of dice, 1. max value, 2. bonus)
            //     for (var i = 0; i < 3; i++) {
            //         numbers[i] = parseInt(words[1].match(/[0-9]+/g)[i]);
            //     }

            //     // roll numbers[0] dice
            //     for (var j = 0; j < numbers[0]; j++) {
            //         total += Math.ceil(Math.random() * numbers[1]);
            //     }

            //     // add bonus, send final message
            //     total += numbers[2];
            //     bot.sendMessage(message.channel, "You rolled a " + Math.ceil(total));
            // } else {
            //     bot.sendMessage(message.channel, invalidMessage);
            // }
            return;
        },
        changesheet: function(message) {
            var newSheet = updateCharSheet(message);
            if (newSheet === null) {
                poorSyntax("!sheet", message);
                return;
            } else if (newSheet === "TOBEDELETED") {
                charSheets[message.author.id] = undefined;
            } else {
                charSheets[message.author.id] = newSheet;
            }
            //dangerous -- remove below after functions finished
            writeToSheet();
            return;
        },
        printsheet: function(message) {
            var outputString = printSheet(message.author.id);
            if (!outputString) {
                poorSyntax("!mysheet", message);
                return;
            } else {
                bot.sendMessage(message.channel, outputString);
            }
            return;
        }
    };
};<|endoftext|>


<commit_before>/**
 * Class of managing Filtering and displaying of records.
 *
 * @returns {Records}
 */
function Records() {
    /**
     * Object of datatable.
     */
//	this.oTable = null;
    /**
     * URL for managing calls of datatable
     * @type {string}
     */
    var ajaxSource = null;
    var pageUrl = null;
    var selfObj = this;
    var Filters = new Object();
    var customFieldName = 'All';
    var customColumnName = 'all';
    var ajaxSaveStateUrl = null;
    /**
     * Set the ajax URL of datatable.
     * @param {string} source
     *
     */
    this.setAjaxSource = function (source) {
        ajaxSource = source;

    }
    /**
     * Set the ajax URL for selected rows of datatable.
     * @param {string} source
     *
     */
    this.setAjaxSaveStateUrl = function (source) {
        ajaxSaveStateUrl = source;

    }
    /**
     * Set the page url.
     * @param {string} url
     *
     */
    this.setPageUrl = function (url) {
        pageUrl = url;

    }
    /**
     * Initialize the datatable.
     *
     */
    this.initDataTable = function () {
        // check the existence of table on which we are going to apply datatable.
        if ($('#records').length > 0)
        {
            // Modify css for managing view.
//			$('#container').removeClass('container');
//			$('#container').css('margin', '20px');
            var selected = [];
            oTable =
                    $('#records').dataTable(
                    {
                        "dom": '<"top"p><"clear">tir<"bottom"p>',
                        "bProcessing": true,
                        "bServerSide": true,
                        retrieve: true,
                        destroy: true,
                        "language": {
                            "info": "Showing _START_ - _END_ of _MAX_",
                            "infoFiltered": ''
                        },
                        "aoColumnDefs": [
                            {"bSortable": false, "aTargets": [0]}
                        ],
                        "aaSorting": [],
                        "sAjaxSource": ajaxSource,
                        "bStateSave": true,
//				"fnInitComplete": function () {
//					this.oTable.fnAdjustColumnSizing();
//				},
                        "fnServerData": function (sSource, aoData, fnCallback) {
                            jQuery.getJSON(sSource, aoData, function (json) {
                                fnCallback(json);

                            });
                        },
                        "createdRow": function (row, data, index) {
                            var input = $(row).find("td:first").html();
                            row.id = "row-" + $(input).attr('value');
                        },
                        "ajax": ajaxSource,
                        "rowCallback": function (row, data) {
                            if ($.inArray(row.id, selected) !== -1) {
                                $(row).addClass('selected');
                                    var input = $("#" + row.id + " td:first").html();
                                    console.log(input);
                                    $("#" + $(input).attr('id')).attr("checked", "checked");
                                    $("#" + $(input).attr('id')).prop("checked", true);
                            }
                        }
                    });
            $('#records tbody').on('click', 'tr', function () {
                var id = this.id;
                var index = $.inArray(id, selected);
                if (index === -1) {
                    selected.push(id);
                } else {
                    selected.splice(index, 1);
                }
                $(this).toggleClass('selected', function () {
                    var input = $("#" + id + " td:first").html();
                    if ($(this).hasClass('selected') === true) {
                        $("#" + $(input).attr('id')).attr("checked", "checked");
                        $("#" + $(input).attr('id')).prop("checked", true);
                    } else {
                        $("#" + $(input).attr('id')).removeAttr("checked");
                    }
                });

            });
        }

    }
    /**
     *
     * @returns {Boolean}
     */
    this.bindEvents = function () {
        selfObj.isAnySearch();
        $('input[name="mediaType[]"]').click(function () {
            checkParentFacet('media_type', $(this).prop("checked"));
        });
        $('input[name="commercial[]"]').click(function () {
            checkParentFacet('commercial', $(this).prop('checked'));
        });
        $('input[name="format[]"]').click(function () {
            checkParentFacet('format', $(this).prop('checked'));
        });
        $('input[name="base[]"]').click(function () {
            checkParentFacet('base', $(this).prop('checked'));
        });
        $('input[name="recordingStandard[]"]').click(function () {
            checkParentFacet('recordingStandard', $(this).prop('checked'));
        });
        $('input[name="printType[]"]').click(function () {
            checkParentFacet('printType', $(this).prop('checked'));
        });
        $('input[name="project[]"]').click(function () {
            checkParentFacet('project', $(this).prop('checked'));
        });
        $('input[name="reelDiameter[]"]').click(function () {
            checkParentFacet('reelDiameter', $(this).prop('checked'));
        });
        $('input[name="discDiameter[]"]').click(function () {
            checkParentFacet('discDiameter', $(this).prop('checked'));
        });
        $('input[name="acidDetection[]"]').click(function () {
            checkParentFacet('acidDetection', $(this).prop('checked'));
        });
        $('input[name="collectionName[]"]').click(function () {
            checkParentFacet('collectionName', $(this).prop('checked'));
        });
        initTriStateCheckBox('is_review_check', 'is_review_check_state', true);
        $('#is_review_check').click(function () {
            var totalChecked = $('#total_checked').val();
            var containerId = $(this).attr('id');
            var currentVal = $('#' + containerId + '_state').val();
            if (currentVal > 0 && totalChecked == 0)
            {
                totalChecked++;
                $('#parent_facet').val(containerId);
                $('#total_checked').val(totalChecked);
            }
            if (currentVal == 0 && $('#parent_facet').val() == containerId) {
                totalChecked--;
                $('#parent_facet').val('');
                $('#total_checked').val(totalChecked);
            }
            filterRecords();
        });
        $('#reset_all').click(function () {
            selfObj.resetAll();
        });

        selfObj.addCustomToken();
        $('#addKeyword').click(function () {
            selfObj.addKeyword();
        });
        $('#keywordSearch').keypress(function (e) {
            if (e.which == 13) {
                selfObj.addKeyword();
            }
        });

        selfObj.removeFilter();
        selfObj.removeKeywordFilter();
        return true;
    }
    /**
     *
     * @param {type} type
     * @param {type} isChecked
     * @returns {undefined}
     */
    var checkParentFacet = function (type, isChecked) {
        //todo need to update function
        var totalChecked = $('#total_checked').val();
        var total = $('#facet_sidebar input:checked').length;
        if (total == 0)
            totalChecked = 0;
        if (isChecked)
            totalChecked++;
        else
            totalChecked--;
        if (totalChecked < 0)
            totalChecked = 0;
        $('#total_checked').val(totalChecked);

        if ($('#parent_facet').val() == '' && totalChecked == 1)
            $('#parent_facet').val(type);
        else if (totalChecked == 0)
            $('#parent_facet').val('');
        filterRecords();
    }
    /**
     *
     * @returns {undefined}
     */
    var filterRecords = function () {
        $.blockUI({
            message: 'Please wait...',
            css: {
                border: 'none',
                padding: '15px',
                backgroundColor: '#000',
                '-webkit-border-radius': '10px',
                '-moz-border-radius': '10px',
                opacity: .5,
                color: '#fff',
                zIndex: 999999
            }
        });
        $.ajax({
            type: 'GET',
            url: pageUrl,
            data: $('#formSearch').serialize(),
            dataType: 'json',
            success: function (response)
            {
                $("#recordsContainer").html(response.html);
                var source = $('#metro-js').attr('src');
                var script = document.createElement("script");
                script.type = "text/javascript";
                script.src = source;
                script.id = "metro-js";
                $("#recordsContainer").append(script);
                selfObj.initDataTable();
                selfObj.bindEvents();
                $('body').scrollTop(0);
                $.unblockUI();
            }

        });
    }

    /**
     *
     * @returns {undefined}
     */
    this.addCustomToken = function () {
        $('.customToken').click(function () {
            customFieldName = $(this).attr('data-fieldName');
            customColumnName = $(this).attr('data-columnName');
            $('#limit_field_text').html(customFieldName);
        });
    }

    this.addKeyword = function () {

        if ($('#keywordSearch').val() != '') {
            if ($('#facet_keyword_search').val() != '' && $('#facet_keyword_search').val() != '""') {
                Filters = JSON.parse($('#facet_keyword_search').val());
            }
            else {
                Filters = new Array();
            }
            for (x in Filters) {
                if (Filters[x].value == $('#keywordSearch').val()) {
                    alert($('#keywordSearch').val() + " filter is already applied.");
                    return false;
                }
            }
            var temp = {};
            temp.value = $('#keywordSearch').val();
            temp.type = customColumnName;
            Filters.push(temp);

            $('#facet_keyword_search').val(JSON.stringify(Filters));
            customFieldName = 'All';
            customColumnName = 'all';
            filterRecords();
        }
    }

    this.removeFilter = function () {
        $('.delFilter').click(function () {
            elementID = $(this).attr('data-elementId');
            type = $(this).attr('data-type');
            $('#' + elementID).prop('checked', false);
            checkParentFacet(type);
        });
    }
    this.removeKeywordFilter = function () {
        $('.deleteKeyword').click(function () {
            var index = $.trim($(this).data().index);
            Filters = JSON.parse($('#facet_keyword_search').val());
            delete (Filters[index]);
            Filters.splice(index, 1);
            $('#facet_keyword_search').val(JSON.stringify(Filters));
            filterRecords();
        });

    }
    this.resetAll = function () {
        $('#formSearch').find('input:hidden, input:text, select').val('');
        $('#formSearch').find('input:radio, input:checkbox')
                .removeAttr('checked').removeAttr('selected');
        filterRecords();
    }
    this.isAnySearch = function () {
        if ($('.search_keys').length > 0) {
            $('#reset_all').show();
        }
        else {
            $('#reset_all').hide();

        }

    }
}

<commit_msg>tr selected<commit_after>/**
 * Class of managing Filtering and displaying of records.
 *
 * @returns {Records}
 */
function Records() {
    /**
     * Object of datatable.
     */
//	this.oTable = null;
    /**
     * URL for managing calls of datatable
     * @type {string}
     */
    var ajaxSource = null;
    var pageUrl = null;
    var selfObj = this;
    var Filters = new Object();
    var customFieldName = 'All';
    var customColumnName = 'all';
    var ajaxSaveStateUrl = null;
    /**
     * Set the ajax URL of datatable.
     * @param {string} source
     *
     */
    this.setAjaxSource = function (source) {
        ajaxSource = source;

    }
    /**
     * Set the ajax URL for selected rows of datatable.
     * @param {string} source
     *
     */
    this.setAjaxSaveStateUrl = function (source) {
        ajaxSaveStateUrl = source;

    }
    /**
     * Set the page url.
     * @param {string} url
     *
     */
    this.setPageUrl = function (url) {
        pageUrl = url;

    }
    /**
     * Initialize the datatable.
     *
     */
    this.initDataTable = function () {
        // check the existence of table on which we are going to apply datatable.
        if ($('#records').length > 0)
        {
            // Modify css for managing view.
//			$('#container').removeClass('container');
//			$('#container').css('margin', '20px');
            var selected = [];
            oTable =
                    $('#records').dataTable(
                    {
                        "dom": '<"top"p><"clear">tir<"bottom"p>',
                        "bProcessing": true,
                        "bServerSide": true,
                        retrieve: true,
                        destroy: true,
                        "language": {
                            "info": "Showing _START_ - _END_ of _MAX_",
                            "infoFiltered": ''
                        },
                        "aoColumnDefs": [
                            {"bSortable": false, "aTargets": [0]}
                        ],
                        "aaSorting": [],
                        "sAjaxSource": ajaxSource,
                        "bStateSave": true,
//				"fnInitComplete": function () {
//					this.oTable.fnAdjustColumnSizing();
//				},
                        "fnServerData": function (sSource, aoData, fnCallback) {
                            jQuery.getJSON(sSource, aoData, function (json) {
                                fnCallback(json);

                            });
                        },
                        "createdRow": function (row, data, index) {
                            var input = $(row).find("td:first").html();
                            row.id = "row-" + $(input).attr('value');
                        },
                        "ajax": ajaxSource,
                        "rowCallback": function (row, data) {
                            if ($.inArray(row.id, selected) !== -1) {
                                $(row).addClass('selected');
                                    var input = $("#" + row.id + " td:first").html();
                                    console.log(row.id);
                                    $("#" + $(input).attr('id')).attr("checked", "checked");
                                    $("#" + $(input).attr('id')).prop("checked", true);
                            }
                        }
                    });
            $('#records tbody').on('click', 'tr', function () {
                var id = this.id;
                var index = $.inArray(id, selected);
                if (index === -1) {
                    selected.push(id);
                } else {
                    selected.splice(index, 1);
                }
                $(this).toggleClass('selected', function () {
                    var input = $("#" + id + " td:first").html();
                    if ($(this).hasClass('selected') === true) {
                        $("#" + $(input).attr('id')).attr("checked", "checked");
                        $("#" + $(input).attr('id')).prop("checked", true);
                    } else {
                        $("#" + $(input).attr('id')).removeAttr("checked");
                    }
                });

            });
        }

    }
    /**
     *
     * @returns {Boolean}
     */
    this.bindEvents = function () {
        selfObj.isAnySearch();
        $('input[name="mediaType[]"]').click(function () {
            checkParentFacet('media_type', $(this).prop("checked"));
        });
        $('input[name="commercial[]"]').click(function () {
            checkParentFacet('commercial', $(this).prop('checked'));
        });
        $('input[name="format[]"]').click(function () {
            checkParentFacet('format', $(this).prop('checked'));
        });
        $('input[name="base[]"]').click(function () {
            checkParentFacet('base', $(this).prop('checked'));
        });
        $('input[name="recordingStandard[]"]').click(function () {
            checkParentFacet('recordingStandard', $(this).prop('checked'));
        });
        $('input[name="printType[]"]').click(function () {
            checkParentFacet('printType', $(this).prop('checked'));
        });
        $('input[name="project[]"]').click(function () {
            checkParentFacet('project', $(this).prop('checked'));
        });
        $('input[name="reelDiameter[]"]').click(function () {
            checkParentFacet('reelDiameter', $(this).prop('checked'));
        });
        $('input[name="discDiameter[]"]').click(function () {
            checkParentFacet('discDiameter', $(this).prop('checked'));
        });
        $('input[name="acidDetection[]"]').click(function () {
            checkParentFacet('acidDetection', $(this).prop('checked'));
        });
        $('input[name="collectionName[]"]').click(function () {
            checkParentFacet('collectionName', $(this).prop('checked'));
        });
        initTriStateCheckBox('is_review_check', 'is_review_check_state', true);
        $('#is_review_check').click(function () {
            var totalChecked = $('#total_checked').val();
            var containerId = $(this).attr('id');
            var currentVal = $('#' + containerId + '_state').val();
            if (currentVal > 0 && totalChecked == 0)
            {
                totalChecked++;
                $('#parent_facet').val(containerId);
                $('#total_checked').val(totalChecked);
            }
            if (currentVal == 0 && $('#parent_facet').val() == containerId) {
                totalChecked--;
                $('#parent_facet').val('');
                $('#total_checked').val(totalChecked);
            }
            filterRecords();
        });
        $('#reset_all').click(function () {
            selfObj.resetAll();
        });

        selfObj.addCustomToken();
        $('#addKeyword').click(function () {
            selfObj.addKeyword();
        });
        $('#keywordSearch').keypress(function (e) {
            if (e.which == 13) {
                selfObj.addKeyword();
            }
        });

        selfObj.removeFilter();
        selfObj.removeKeywordFilter();
        return true;
    }
    /**
     *
     * @param {type} type
     * @param {type} isChecked
     * @returns {undefined}
     */
    var checkParentFacet = function (type, isChecked) {
        //todo need to update function
        var totalChecked = $('#total_checked').val();
        var total = $('#facet_sidebar input:checked').length;
        if (total == 0)
            totalChecked = 0;
        if (isChecked)
            totalChecked++;
        else
            totalChecked--;
        if (totalChecked < 0)
            totalChecked = 0;
        $('#total_checked').val(totalChecked);

        if ($('#parent_facet').val() == '' && totalChecked == 1)
            $('#parent_facet').val(type);
        else if (totalChecked == 0)
            $('#parent_facet').val('');
        filterRecords();
    }
    /**
     *
     * @returns {undefined}
     */
    var filterRecords = function () {
        $.blockUI({
            message: 'Please wait...',
            css: {
                border: 'none',
                padding: '15px',
                backgroundColor: '#000',
                '-webkit-border-radius': '10px',
                '-moz-border-radius': '10px',
                opacity: .5,
                color: '#fff',
                zIndex: 999999
            }
        });
        $.ajax({
            type: 'GET',
            url: pageUrl,
            data: $('#formSearch').serialize(),
            dataType: 'json',
            success: function (response)
            {
                $("#recordsContainer").html(response.html);
                var source = $('#metro-js').attr('src');
                var script = document.createElement("script");
                script.type = "text/javascript";
                script.src = source;
                script.id = "metro-js";
                $("#recordsContainer").append(script);
                selfObj.initDataTable();
                selfObj.bindEvents();
                $('body').scrollTop(0);
                $.unblockUI();
            }

        });
    }

    /**
     *
     * @returns {undefined}
     */
    this.addCustomToken = function () {
        $('.customToken').click(function () {
            customFieldName = $(this).attr('data-fieldName');
            customColumnName = $(this).attr('data-columnName');
            $('#limit_field_text').html(customFieldName);
        });
    }

    this.addKeyword = function () {

        if ($('#keywordSearch').val() != '') {
            if ($('#facet_keyword_search').val() != '' && $('#facet_keyword_search').val() != '""') {
                Filters = JSON.parse($('#facet_keyword_search').val());
            }
            else {
                Filters = new Array();
            }
            for (x in Filters) {
                if (Filters[x].value == $('#keywordSearch').val()) {
                    alert($('#keywordSearch').val() + " filter is already applied.");
                    return false;
                }
            }
            var temp = {};
            temp.value = $('#keywordSearch').val();
            temp.type = customColumnName;
            Filters.push(temp);

            $('#facet_keyword_search').val(JSON.stringify(Filters));
            customFieldName = 'All';
            customColumnName = 'all';
            filterRecords();
        }
    }

    this.removeFilter = function () {
        $('.delFilter').click(function () {
            elementID = $(this).attr('data-elementId');
            type = $(this).attr('data-type');
            $('#' + elementID).prop('checked', false);
            checkParentFacet(type);
        });
    }
    this.removeKeywordFilter = function () {
        $('.deleteKeyword').click(function () {
            var index = $.trim($(this).data().index);
            Filters = JSON.parse($('#facet_keyword_search').val());
            delete (Filters[index]);
            Filters.splice(index, 1);
            $('#facet_keyword_search').val(JSON.stringify(Filters));
            filterRecords();
        });

    }
    this.resetAll = function () {
        $('#formSearch').find('input:hidden, input:text, select').val('');
        $('#formSearch').find('input:radio, input:checkbox')
                .removeAttr('checked').removeAttr('selected');
        filterRecords();
    }
    this.isAnySearch = function () {
        if ($('.search_keys').length > 0) {
            $('#reset_all').show();
        }
        else {
            $('#reset_all').hide();

        }

    }
}

<|endoftext|>


<commit_before>/* global gear_combinations, _, Fraction */
/* global gear_sizes */
/* global up_unit_in_mm, across_unit_in_mm */
/* exported combine_head_and_tails, get_total_distance */
/* exported hash_code */
/* exported get_gear_trains */
/* exported all_gear_combinations */
/* exported subtract_combo_from_list_of_objectives */
/* exported get_all_gear_trains */

/* jshint bitwise:false */

// what should a gear_combo look like?
// a gear combo will just be an array of 4 numbers
// [ first_gear, second_gear, up, across ]
//
//

function hash_code(str) {
  "use strict";
  var hash = 0;
  if (str.length === 0) {
    return hash;
  }
  for (var i = 0; i < str.length; i++) {
    var character = str.charCodeAt(i);
    hash = ((hash << 5) - hash) + character;
    hash = hash & hash; // Convert to 32bit integer
  }
  return hash;
}

// is array in the array_of_arrays?
function deeply_contains(array_of_arrays, array_to_find) {
  "use strict";
  return _.some(array_of_arrays,
    function(array) {
      return _.isEqual(array_to_find, array);
    });
}

// takes an array and returns an array with duplicates removed.
// the constituent arrays just references to the arrays in the argument
// array
function deeply_unique(array_of_arrays) {
  "use strict";
  var array_to_return = [];
  _.each(array_of_arrays,
    function(array) {
      if (false === deeply_contains(array_to_return, array)) {
        array_to_return.push(array);
      }
    });
  return array_to_return;
}

function get_gear_combinations(negative_movements_allowed) {
  "use strict";

  function add_inverses_and_remove_duplicates(combos) {
    var combos_switched = _.map(combos,
      function(gear_combo) {
        return [gear_combo[1], gear_combo[0], gear_combo[2], gear_combo[3]];
      });
    return deeply_unique(_.cat(combos, combos_switched));
  }

  var first_quadrant = _.flatten(_.map(gear_combinations,
    // compacted_combos would look like [40,36,[[up, across], [up,across]]]
    //
    // we'd want to return an array of gear_combos
    function(compacted_combos) {
      return _.map(compacted_combos[2],
        function(up_and_across) {
          return [
            compacted_combos[0],
            compacted_combos[1],
            up_and_across[0],
            up_and_across[1]
          ];
        });
    }), true);

  if (!negative_movements_allowed) {
    return add_inverses_and_remove_duplicates(first_quadrant);
  }

  var second_quadrant = _.map(first_quadrant,
    function(gear_combo) {
      var cloned = _.clone(gear_combo);
      // have to do this because underscore.js considers 0 not equal to -0
      cloned[3] = gear_combo[3] === 0 ? gear_combo[3] : -gear_combo[3];
      return cloned;
    });
  var third_quadrant = _.map(first_quadrant,
    function(gear_combo) {
      var cloned = _.clone(gear_combo);
      cloned[3] = gear_combo[3] === 0 ? gear_combo[3] : -gear_combo[3];
      cloned[2] = gear_combo[2] === 0 ? gear_combo[2] : -gear_combo[2];
      return cloned;
    });
  var fourth_quadrant = _.map(first_quadrant,
    function(gear_combo) {
      var cloned = _.clone(gear_combo);
      cloned[2] = gear_combo[2] === 0 ? gear_combo[2] : -gear_combo[2];
      return cloned;
    });
  var all_quadrants = _.cat(first_quadrant, second_quadrant, third_quadrant, fourth_quadrant);
  return add_inverses_and_remove_duplicates(all_quadrants);
}

// return a list of gear-trains
function combine_head_and_tails(head_combo, tail_trains) {
  "use strict";
  // if tail-trains is false, that means no solution could be found,
  // propogate the false
  if (tail_trains === false) {
    return false;
  } else if (tail_trains.length === 0) {
    // two arrays enclose the head-combo, this is because one is for turning the
    // head-combo into a gear-train, and the other is for making it a list of
    // gear-trains.
    return [[head_combo]];
  } else {
    return _.map(tail_trains,
      function(tail_train) {
        return _.cat([head_combo], tail_train);
      });
  }
}

function get_total_distance(up, across, up_unit, across_unit) {
  "use strict";
  return Math.sqrt(Math.pow(up_unit * up, 2) + Math.pow(across_unit * across, 2));
}

// not going to worry about multiple objectives
function get_all_gear_trains(up, across, ratio, negative_movements_allowed, two_gears_on_one_axle_allowed) {
  "use strict";

  var gear_combinations = get_gear_combinations(negative_movements_allowed);

  // returns an array of gear_trains
  var get_gear_trains = _.memoize(function(up, across, ratio, previous_gear) {
      if (up === 0 && across === 0) {
        if (typeof ratio === "undefined" || ratio.toDouble() === 1) {
          // !!! not sure if this is right
          return [];
        } else {
          // ratio objective was not met
          return false;
        }
      }

      // gear_trains is an array whos elements are either false or arrays of solutions. we're going
      // to have to get rid of the falsey values with _.filter, and flatten the array of arrays of
      // solutions into an array of solutions.
      var gear_trains = _.map(gear_combinations,
        // each combo will return either false or a list of solutions. so we're going to want to flatten
        function(combo) {
          if (negative_movements_allowed === false && (combo[2] < 0 || combo[3] < 0)) {
            return false;
          }
          if (two_gears_on_one_axle_allowed === false && previous_gear !== combo[0]) {
            return false;
          }
          var up_left = up - combo[2];
          var across_left = across - combo[3];
          var new_ratio;
          if (typeof ratio !== "undefined") {
            new_ratio = (new Fraction(ratio)).mul(-combo[0], combo[1]);
          }
          if (1 + get_total_distance(up_left, across_left, up_unit_in_mm, across_unit_in_mm) < get_total_distance(up, across, up_unit_in_mm, across_unit_in_mm)) {
            return combine_head_and_tails(combo, get_gear_trains(up_left, across_left, new_ratio, combo[1]));
          } else {
            return false;
          }
        });
      // get rid of the falsey values
      gear_trains = _.filter(gear_trains, function(gear_train) {
        return gear_train;
      });
      // flatten the array of arrays of solutions into an array of solutions
      gear_trains = _.flatten(gear_trains, true);

      if (gear_trains.length === 0) {
        return false;
      } else {
        return gear_trains;
      }
    },
    // this is the hash function. the arguments to it would be (list_of_objectives_left, previous_gear, and optionals)
    function(up, across, ratio, previous_gear, negative_movements_allowed, two_gears_on_one_axle_allowed) {
      // turn into an array, then JSON it, then hash it
      var argument_array = [up, across, ratio, previous_gear, negative_movements_allowed, two_gears_on_one_axle_allowed];
      return (hash_code(JSON.stringify(argument_array)));
    });

  negative_movements_allowed = negative_movements_allowed ? true : false;
  two_gears_on_one_axle_allowed = two_gears_on_one_axle_allowed ? true : false;

  // if the ratio exists, turn it into a Fraction
  if (typeof ratio !== "undefined") {
    if (ratio.constructor.name !== "Fraction") {
      ratio = new Fraction(ratio);
    }
  }

  var starting_gears;
  if (two_gears_on_one_axle_allowed === true) {
    starting_gears = [0];
  } else {
    starting_gears = gear_sizes;
  }

  var gear_trains = _.map(starting_gears,
    function(starting_gear) {
      return get_gear_trains(up, across, ratio, starting_gear);
    });

  gear_trains = _.filter(gear_trains, function(gear_train) {
    return gear_train;
  });

  // flatten the array of arrays of solutions into an array of solutions
  gear_trains = _.flatten(gear_trains, true);

  // sort by shortest gear train first
  gear_trains = _.sortBy(gear_trains, "length");
  return gear_trains;
}
<commit_msg>- added an object pool for the Fractions<commit_after>/* global gear_combinations, _, Fraction */
/* global gear_sizes */
/* global up_unit_in_mm, across_unit_in_mm */
/* exported combine_head_and_tails, get_total_distance */
/* exported hash_code */
/* exported get_gear_trains */
/* exported all_gear_combinations */
/* exported subtract_combo_from_list_of_objectives */
/* exported get_all_gear_trains */

/* jshint bitwise:false */

// what should a gear_combo look like?
// a gear combo will just be an array of 4 numbers
// [ first_gear, second_gear, up, across ]
//
//

function hash_code(str) {
  "use strict";
  var hash = 0;
  if (str.length === 0) {
    return hash;
  }
  for (var i = 0; i < str.length; i++) {
    var character = str.charCodeAt(i);
    hash = ((hash << 5) - hash) + character;
    hash = hash & hash; // Convert to 32bit integer
  }
  return hash;
}

// is array in the array_of_arrays?
function deeply_contains(array_of_arrays, array_to_find) {
  "use strict";
  return _.some(array_of_arrays,
    function(array) {
      return _.isEqual(array_to_find, array);
    });
}

// takes an array and returns an array with duplicates removed.
// the constituent arrays just references to the arrays in the argument
// array
function deeply_unique(array_of_arrays) {
  "use strict";
  var array_to_return = [];
  _.each(array_of_arrays,
    function(array) {
      if (false === deeply_contains(array_to_return, array)) {
        array_to_return.push(array);
      }
    });
  return array_to_return;
}

function get_gear_combinations(negative_movements_allowed) {
  "use strict";

  function add_inverses_and_remove_duplicates(combos) {
    var combos_switched = _.map(combos,
      function(gear_combo) {
        return [gear_combo[1], gear_combo[0], gear_combo[2], gear_combo[3]];
      });
    return deeply_unique(_.cat(combos, combos_switched));
  }

  var first_quadrant = _.flatten(_.map(gear_combinations,
    // compacted_combos would look like [40,36,[[up, across], [up,across]]]
    //
    // we'd want to return an array of gear_combos
    function(compacted_combos) {
      return _.map(compacted_combos[2],
        function(up_and_across) {
          return [
            compacted_combos[0],
            compacted_combos[1],
            up_and_across[0],
            up_and_across[1]
          ];
        });
    }), true);

  if (!negative_movements_allowed) {
    return add_inverses_and_remove_duplicates(first_quadrant);
  }

  var second_quadrant = _.map(first_quadrant,
    function(gear_combo) {
      var cloned = _.clone(gear_combo);
      // have to do this because underscore.js considers 0 not equal to -0
      cloned[3] = gear_combo[3] === 0 ? gear_combo[3] : -gear_combo[3];
      return cloned;
    });
  var third_quadrant = _.map(first_quadrant,
    function(gear_combo) {
      var cloned = _.clone(gear_combo);
      cloned[3] = gear_combo[3] === 0 ? gear_combo[3] : -gear_combo[3];
      cloned[2] = gear_combo[2] === 0 ? gear_combo[2] : -gear_combo[2];
      return cloned;
    });
  var fourth_quadrant = _.map(first_quadrant,
    function(gear_combo) {
      var cloned = _.clone(gear_combo);
      cloned[2] = gear_combo[2] === 0 ? gear_combo[2] : -gear_combo[2];
      return cloned;
    });
  var all_quadrants = _.cat(first_quadrant, second_quadrant, third_quadrant, fourth_quadrant);
  return add_inverses_and_remove_duplicates(all_quadrants);
}

// return a list of gear-trains
function combine_head_and_tails(head_combo, tail_trains) {
  "use strict";
  // if tail-trains is false, that means no solution could be found,
  // propogate the false
  if (tail_trains === false) {
    return false;
  } else if (tail_trains.length === 0) {
    // two arrays enclose the head-combo, this is because one is for turning the
    // head-combo into a gear-train, and the other is for making it a list of
    // gear-trains.
    return [[head_combo]];
  } else {
    return _.map(tail_trains,
      function(tail_train) {
        return _.cat([head_combo], tail_train);
      });
  }
}

function get_total_distance(up, across, up_unit, across_unit) {
  "use strict";
  return Math.sqrt(Math.pow(up_unit * up, 2) + Math.pow(across_unit * across, 2));
}

// Fraction object pool

// fraction_pool is an array of objects
// the object looks like { fraction: fraction_object, in_use: true }
var fraction_pool = [];

var new_fraction = 0;
var recycled_fraction = 0;

//
function get_unused_fraction() {
  "use strict";

  // try to go through all of the fraction pool to find an available fraction
  var found_fraction = _.findWhere(fraction_pool, {
    in_use: false
  });
  if (typeof found_fraction === "undefined") {
    found_fraction = {
      fraction: new Fraction(0),
      in_use: true
    };
    new_fraction++;
    fraction_pool.push(found_fraction);
  } else {
    found_fraction.in_use = true;
    recycled_fraction++;
  }
  return found_fraction;
}

function free_fraction(ratio_from_pool) {
  "use strict";
  ratio_from_pool.in_use = false;
}

// not going to worry about multiple objectives
function get_all_gear_trains(up, across, ratio, negative_movements_allowed, two_gears_on_one_axle_allowed) {
  "use strict";

  var gear_combinations = get_gear_combinations(negative_movements_allowed);

  // returns an array of gear_trains
  var get_gear_trains = _.memoize(function(up, across, ratio_from_pool, previous_gear) {
      if (up === 0 && across === 0) {
        if (typeof ratio_from_pool === "undefined" || ratio_from_pool.fraction.toDouble() === 1) {
          return [];
        } else {
          // ratio objective was not met
          return false;
        }
      }

      // gear_trains is an array whos elements are either false or arrays of solutions. we're going
      // to have to get rid of the falsey values with _.filter, and flatten the array of arrays of
      // solutions into an array of solutions.
      var gear_trains = _.map(gear_combinations,
        // each combo will return either false or a list of solutions. so we're going to want to flatten
        function(combo) {
          if (negative_movements_allowed === false && (combo[2] < 0 || combo[3] < 0)) {
            return false;
          }
          if (two_gears_on_one_axle_allowed === false && previous_gear !== combo[0]) {
            return false;
          }
          var up_left = up - combo[2];
          var across_left = across - combo[3];
          var new_ratio_from_pool;
          if (typeof ratio_from_pool !== "undefined") {
            // get new Fraction from Fraction object pool
            new_ratio_from_pool = get_unused_fraction();
            new_ratio_from_pool.fraction.set(ratio_from_pool.fraction);
            new_ratio_from_pool.fraction.mul(-combo[0], combo[1]);
          }
          if (1 + get_total_distance(up_left, across_left, up_unit_in_mm, across_unit_in_mm) < get_total_distance(up, across, up_unit_in_mm, across_unit_in_mm)) {
            var partial_gear_trains = combine_head_and_tails(combo, get_gear_trains(up_left, across_left, new_ratio_from_pool, combo[1]));
            free_fraction(new_ratio_from_pool);
            return partial_gear_trains;
          } else {
            free_fraction(new_ratio_from_pool);
            return false;
          }
        });
      // get rid of the falsey values
      gear_trains = _.filter(gear_trains, function(gear_train) {
        return gear_train;
      });
      // flatten the array of arrays of solutions into an array of solutions
      gear_trains = _.flatten(gear_trains, true);

      if (gear_trains.length === 0) {
        return false;
      } else {
        return gear_trains;
      }
    },
    // this is the hash function. the arguments to it would be (list_of_objectives_left, previous_gear, and optionals)
    function(up, across, ratio_from_pool, previous_gear, negative_movements_allowed, two_gears_on_one_axle_allowed) {
      // turn into an array, then JSON it, then hash it
      var argument_array = [up, across, ratio_from_pool.fraction, previous_gear, negative_movements_allowed, two_gears_on_one_axle_allowed];
      return (hash_code(JSON.stringify(argument_array)));
    });

  negative_movements_allowed = negative_movements_allowed ? true : false;
  two_gears_on_one_axle_allowed = two_gears_on_one_axle_allowed ? true : false;

  var ratio_from_pool;

  // if the ratio exists, turn it into a Fraction
  if (typeof ratio !== "undefined") {
    ratio_from_pool = get_unused_fraction();
    ratio_from_pool.fraction.set(ratio);
  }

  var starting_gears;
  if (two_gears_on_one_axle_allowed === true) {
    starting_gears = [0];
  } else {
    starting_gears = gear_sizes;
  }

  var gear_trains = _.map(starting_gears,
    function(starting_gear) {
      return get_gear_trains(up, across, ratio_from_pool, starting_gear);
    });

  gear_trains = _.filter(gear_trains, function(gear_train) {
    return gear_train;
  });

  // flatten the array of arrays of solutions into an array of solutions
  gear_trains = _.flatten(gear_trains, true);

  // sort by shortest gear train first
  gear_trains = _.sortBy(gear_trains, "length");
  return gear_trains;
}
<|endoftext|>