function LCostCalc () {
    var obj = $L.object(this);
    
    obj.packageData = '';
    
    obj.init = function( packageData ) {
        obj._packageData = packageData;
        obj._runFilter($jq('#paperType').parents('li').get(0));
        
        $jq('.LSelectorSelect').bind('change', function(){
            obj._runFilter(this);
        });
        $jq('#bookCalcButton').bind('click', function () {
            $jq('#responseField').hide();
            $jq('#errorField').hide();
            $jq('#shippingNoteField').hide();
            $jq('#calculatingField').show();
            pageCount = parseInt($jq('#fPageCount').val());
            if ( isNaN(pageCount) ) {
                pageCount = 0;
            }
            $jq('#fPageCount').val(pageCount);
            bookCount = parseInt($jq('#fBookCount').val());
            if ( isNaN(bookCount) || bookCount <= 0 ) {
                bookCount = 1;
            }
            $jq('#fBookCount').val(bookCount);
            $jq.ajax({
                url: '/calculators/bookCalcEndpoint.php',
                data: 'fPackageID='+$jq('#fPackageID').val()+'&fPageCount='+pageCount+'&fBookCount='+bookCount+'&fCurrencyCode='+$jq('#fCurrencyCode').val(),
                dataType: 'json',
                success: function (msg) {
                    $jq('#calculatingField').hide();
                    if(msg.severity) {
                        $jq('#errorField').show()
                            .find('.minPage').text(msg.minPages).end()
                            .find('.maxPage').text(msg.maxPages);
                    } else {
                        if(msg.totalCost == msg.costPerUnit) {
                            $jq('#responseField #pageRange').hide();
                        } else {
                            $jq('#responseField #pageRange').show();                            
                        }
                        if (msg.usOnly) {
                            $jq('#shippingNoteField').show();
                        }
                        $jq('#responseField').show()
                            .find('.totalCost').text(msg.totalCost).end()
                            .find('.unitCost').text(msg.costPerUnit);
                    }
                }
            });
            return false;
        });
    };
    
    obj._updateSelections = function ( optionNdx ) {
        var filterOptions = $jq('.LSelectorView.filterOption');
        for (var i=optionNdx+1; i < filterOptions.length; i++) {
            var optionId = filterOptions.eq(i).attr('id');
            if ( $jq('#'+optionId+'.LSelectorView option:selected:hidden').length > 0 ) {
                $jq('#'+optionId+'.LSelectorView option:not(:hidden)').get(0).selected = true;
            }
        }
	};

    obj._runFilter = function (element) {
        var filterInfo = obj._getFilterInfo($jq(element).find('option:selected'));
        if (filterInfo.filter) {
            var filterParent = $jq(element).parents('.LSelectorView').attr('id');
            var optionNdx = $jq('.LSelectorView.filterOption').index($jq(element).parents('.LSelectorView').get(0));
            obj._filterOptions(filterInfo.filter, optionNdx, filterParent);
        }
        obj._setPackageId();
    };
    
    obj._filterOptions = function( filterClass, optionNdx, parentId ) {
        var filterClasses = '';
        var filterOptions = $jq('.LSelectorView.filterOption');
        for (var i=0; i <= optionNdx; i++) {
            var filterInfo = obj._getFilterInfo(filterOptions.eq(i).find('li:has(input:checked), option:selected'));
            filterClasses = filterClasses + '.' +filterInfo.filter;
        };
        
        for (var i=optionNdx+1; i < filterOptions.length; i++) {
            var optionId = filterOptions.eq(i).attr('id')
            
            $jq('#'+optionId+'.LSelectorView .LSelectorSelectItem').each(function(){
                obj._disableSelectOption($jq(this));
            });
            var optionIdArray = optionId.split('_');
            $jq('#'+optionIdArray[0]+'Hidden_'+optionIdArray[1]+'.LSelectorView .LSelectorSelectItem'+filterClasses).each(function(){
                obj._enableSelectOption($jq(this));
            });                    

            obj._updateSelections(optionNdx);
            
            var filterInfo = obj._getFilterInfo(filterOptions.eq(i).find('li:has(input:checked), option:selected'));
            filterClasses = filterClasses + '.' +filterInfo.filter;
        };

    };
    
    obj._setPackageId = function () {
        var paperType = $jq('select[name=paperType]').val();
        var bookType = $jq('select[name=bookType]').val();
        var interiorInkColor = $jq('select[name=interiorInkColor]').val();
        var trimSize = $jq('select[name=trimSize]').val();
        var bindingType = $jq('select[name=bindingType]').val();
        var pd = jQuery.grep(obj._packageData, function(n, i){
          return (n.interiorPaperCoating == paperType && n.coverType == bookType && n.interiorInkColor == interiorInkColor && n.trimSizeId == trimSize && n.bindingType == bindingType);
        });

        if (pd.length > 0) {
            $jq('#fPackageID').val(pd[0].packageId);
        } else {
            $jq('#fPackageID').val('-1');
        }
    };
    
    obj._disableOption = function ( element ) {
        element
            .addClass('disabled')
            .find('input').attr('disabled', 'true');
    };
    
    obj._disableSelectOption = function ( element ) {
        var disabledID = element.parent().attr('id') + 'Hidden';
        element.appendTo('#'+disabledID);
    };

    obj._enableOption = function ( element ) {
        element
            .removeClass('disabled')
            .find('input').removeAttr('disabled');
    };
    
    obj._enableSelectOption = function ( element ) {
        var enabledID = element.parent().attr('id').replace('Hidden', '');
        element.appendTo('#'+enabledID);
    };
    
    obj._getFilterInfo = function ( element ) {
        var classes = element.attr('class').split(' ');
        var filter = false;
        var fields = Array();
        jQuery.each(classes, function (i, val) {
            if(val.substr(0,4) == 'fltr') {
                filter = val.substr(5);
            }
            if(val.substr(0,5) == 'field') {
                fields.push(val.substr(6));
            }
        });
        
        return {filter: filter, fields: fields};
    };

    return obj;
};
$L.add('LCostCalc', new LCostCalc());
