﻿(function() {
  var $ = jQuery;

  var mc = {
    /*************************************************
    *  Make sure the user inputs a valid float in the field.
    *************************************************/
    validateFloatOnKeypress: function(e) {
      if (e.which == 44 || e.which == 46) {
        if (this.value.indexOf(',') >= 0 || this.value.indexOf('.') >= 0) { return false; }
        return true;
      }
      return mc.validateIntOnKeypress(e);
    },

    /*************************************************
    *  Make sure the user inputs a valid int in the field.
    *************************************************/
    validateIntOnKeypress: function(e) {
      if (
        e.which != 8 &&                // Backspace
        e.which !== 0 &&               // Special keys
        (e.which < 48 || e.which > 57) // Digits
      ) { return false; }
    },

    /*************************************************
    *  Convert a float to a string, rounded to specified precision.
    *************************************************/
    toFixed: function(value, precision) {
      var power = Math.pow(10, precision || 0);
      return String(Math.round(value * power) / power);
    },

    /*************************************************
    *  Called when the purchase price was modified.
    *************************************************/
    onChangePurchasePrice: function() {
      var $this = $(this);
      var $fieldset = $this.parents('fieldset.marginCalculator');
      $this.removeClass('auto');

      var
        vatPercent = parseFloat($fieldset.find('input.vatPercent').val()) / 100,
        qtyPerPackage = parseFloat($fieldset.find('input.qtyPerPackage').val());

      var purchasePrice = parseFloat(this.value);
      if (isNaN(purchasePrice)) { return false; }

      var
        $marginValue = $fieldset.find('.marginValue input'),
        $marginPercent = $fieldset.find('.marginPercent input');
      var
        marginValue = 0,
        marginPercent = 0;

      if ($marginValue.hasClass('auto')) {
        // Calculate MarginValue from PurchasePrice and MarginPercent
        marginPercent = parseFloat($marginPercent.val());
        if (isNaN(marginPercent)) { return false; }

        marginPercent = marginPercent / 100;
        marginValue = marginPercent * purchasePrice;

        $marginValue.filter('.can')
          .addClass('auto')
          .val(mc.toFixed(marginValue / qtyPerPackage, 2));
        $marginValue.filter('.roll')
          .addClass('auto')
          .val(mc.toFixed(marginValue, 2));
      } else /* if($marginPercent.hasClass('auto')) */{
        // Calculate MarginPercent from PurchasePrice and RollMarginValue
        marginValue = parseFloat($marginValue.filter('.roll').val());
        if (isNaN(marginValue)) { return false; }

        marginPercent = (marginValue / purchasePrice) * 100;
        $marginPercent
          .addClass('auto')
          .val(mc.toFixed(marginPercent, 2));
      }

      var vat = (purchasePrice + marginValue) * vatPercent;
      $fieldset.find('.vat p.can').text(mc.toFixed(vat / qtyPerPackage, 2));
      $fieldset.find('.vat p.roll').text(mc.toFixed(vat, 2));

      var otdPrice = purchasePrice + marginValue + vat;
      $fieldset.find('.otdPrice input.can')
        .addClass('auto')
        .val(mc.toFixed(otdPrice / qtyPerPackage, 2));
      $fieldset.find('.otdPrice input.roll')
        .addClass('auto')
        .val(mc.toFixed(otdPrice, 2));

      mc.updateProfit($fieldset);
      mc.postItem($fieldset);
    },

    /*************************************************
    *  Called when one of the margin literal value is modified.
    *************************************************/
    onChangeMargin: function() {
      var $this = $(this);
      var $fieldset = $this.parents('fieldset.marginCalculator');
      $this.removeClass('auto');

      var
        vatPercent = parseFloat($fieldset.find('input.vatPercent').val()) / 100,
        qtyPerPackage = parseFloat($fieldset.find('input.qtyPerPackage').val());

      var marginValue = parseFloat(this.value);
      if (isNaN(marginValue)) { return false; }

      if ($this.hasClass('can')) {
        marginValue *= qtyPerPackage;
        $this.siblings('input.roll')
          .removeClass('auto')
          .val(mc.toFixed(marginValue, 2));
      } else {
        $this.siblings('input.can')
          .removeClass('auto')
          .val(mc.toFixed(marginValue / qtyPerPackage, 2));
      }

      var
        $purchasePrice = $fieldset.find('.purchasePrice input'),
        $otdPrice = $fieldset.find('.otdPrice input');
      var
        purchasePrice = 0,
        vat = 0,
        otdPrice = 0;

      if ($purchasePrice.hasClass('auto')) {
        // Calculate PurchasePrice and VAT from OtdPrice and MarginValue
        otdPrice = parseFloat($otdPrice.filter('.roll').val());
        if (isNaN(otdPrice)) { return false; }

        var marginPrice = otdPrice / (1 + vatPercent);
        vat = marginPrice * vatPercent;
        purchasePrice = marginPrice - marginValue;

        $purchasePrice.val(mc.toFixed(purchasePrice, 2));
      } else /* if($otdPrice.hasClass('auto')) */{
        // Calculate OtdPrice and VAT from PurchasePrice and MarginValue
        purchasePrice = parseFloat($purchasePrice.val());
        if (isNaN(purchasePrice)) { return false; }

        vat = (purchasePrice + marginValue) * vatPercent;
        otdPrice = purchasePrice + marginValue + vat;
        $fieldset.find('.otdPrice input.can')
          .addClass('auto')
          .val(mc.toFixed(otdPrice / qtyPerPackage, 2));
        $fieldset.find('.otdPrice input.roll')
          .addClass('auto')
          .val(mc.toFixed(otdPrice, 2));
      }

      $fieldset.find('.vat p.can').text(mc.toFixed(vat / qtyPerPackage, 2));
      $fieldset.find('.vat p.roll').text(mc.toFixed(vat, 2));

      var marginPercent = (marginValue / purchasePrice) * 100;
      $fieldset.find('.marginPercent input')
        .addClass('auto')
        .val(mc.toFixed(marginPercent, 2));

      mc.updateProfit($fieldset);
      mc.postItem($fieldset);
    },

    /*************************************************
    *  Called when the margin percent value is modified.
    *************************************************/
    onChangeMarginPercent: function() {
      var $this = $(this);
      var $fieldset = $this.parents('fieldset.marginCalculator');
      $this.removeClass('auto');

      var
        vatPercent = parseFloat($fieldset.find('input.vatPercent').val()) / 100,
        qtyPerPackage = parseFloat($fieldset.find('input.qtyPerPackage').val());

      var marginPercent = parseFloat(this.value);
      if (isNaN(marginPercent)) { return false; }
      marginPercent /= 100;

      var $purchasePrice = $fieldset.find('.purchasePrice input');
      var $otdPrice = $fieldset.find('.otdPrice input');

      var
        otdPrice = 0,
        vat = 0,
        marginValue = 0,
        purchasePrice = 0;

      if ($purchasePrice.hasClass('auto')) {
        // Calculate PurchasePrice, MarginValue and VAT from OtdPrice and MarginPercent
        otdPrice = parseFloat($otdPrice.filter('.roll').val());
        if (isNaN(otdPrice)) { return false; }

        var marginPrice = otdPrice / (1 + vatPercent);
        vat = marginPrice * vatPercent;
        purchasePrice = marginPrice / (1 + marginPercent);
        marginValue = marginPrice - purchasePrice;

        $purchasePrice.val(mc.toFixed(purchasePrice, 2));
      } else /* if($otdPrice.hasClass('auto')) */{
        // Calculate OtdPrice, MarginValue and VAT from PurchasePrice and MarginPercent
        purchasePrice = parseFloat($purchasePrice.val());
        if (isNaN(purchasePrice)) { return false; }

        marginValue = purchasePrice * marginPercent;
        vat = (purchasePrice + marginValue) * vatPercent;

        otdPrice = purchasePrice + marginValue + vat;
        $fieldset.find('.otdPrice input.can')
          .addClass('auto')
          .val(mc.toFixed(otdPrice / qtyPerPackage, 2));
        $fieldset.find('.otdPrice input.roll')
          .addClass('auto')
          .val(mc.toFixed(otdPrice, 2));
      }

      $fieldset.find('.vat p.can').text(mc.toFixed(vat / qtyPerPackage, 2));
      $fieldset.find('.vat p.roll').text(mc.toFixed(vat, 2));

      $fieldset.find('.marginValue input.can')
        .addClass('auto')
        .val(mc.toFixed(marginValue / qtyPerPackage, 2));
      $fieldset.find('.marginValue input.roll')
        .addClass('auto')
        .val(mc.toFixed(marginValue, 2));

      mc.updateProfit($fieldset);
      mc.postItem($fieldset);
    },

    /*************************************************
    *  Called when the OTD price is modified.
    *************************************************/
    onChangeOtdPrice: function() {
      var $this = $(this);
      var $fieldset = $this.parents('fieldset.marginCalculator');
      $this.removeClass('auto');

      var
        vatPercent = parseFloat($fieldset.find('input.vatPercent').val()) / 100,
        qtyPerPackage = parseFloat($fieldset.find('input.qtyPerPackage').val());

      var otdPrice = parseFloat(this.value);
      if (isNaN(otdPrice)) { return false; }

      if ($this.hasClass('can')) {
        otdPrice *= qtyPerPackage;
        $this.siblings('input.roll')
          .removeClass('auto')
          .val(mc.toFixed(otdPrice));
      } else {
        $this.siblings('input.can')
          .removeClass('auto')
          .val(mc.toFixed(otdPrice / qtyPerPackage));
      }

      var marginPrice = otdPrice / (1 + vatPercent);
      var vat = marginPrice * vatPercent;
      $fieldset.find('.vat p.can').text(mc.toFixed(vat / qtyPerPackage, 2));
      $fieldset.find('.vat p.roll').text(mc.toFixed(vat, 2));

      var $marginValue = $fieldset.find('.marginValue input');
      var $marginPercent = $fieldset.find('.marginPercent input');

      var
        marginValue = 0,
        purchasePrice = 0,
        marginPercent = 0;
      if ($marginValue.hasClass('auto')) {
        // Calculate MarginValue and PurchasePrice from OtdPrice and MarginPercent
        marginPercent = parseFloat($marginPercent.val());
        if (isNaN(marginPercent)) { return false; }

        marginPercent = marginPercent / 100;
        purchasePrice = marginPrice / (1 + marginPercent);
        marginValue = marginPrice - purchasePrice;

        $marginValue.filter('.can')
          .addClass('auto')
          .val(mc.toFixed(marginValue / qtyPerPackage, 2));
        $marginValue.filter('.roll')
          .addClass('auto')
          .val(mc.toFixed(marginValue, 2));
      } else /* if($marginPercent.hasClass('auto')) */{
        // Calculate MarginPercent and PurchasePrice from OtdPrice and RollMarginValue
        marginValue = parseFloat($marginValue.filter('.roll').val());
        if (isNaN(marginValue)) { return false; }

        purchasePrice = marginPrice - marginValue;
        marginPercent = (marginValue / purchasePrice) * 100;
        $marginPercent
          .addClass('auto')
          .val(mc.toFixed(marginPercent, 2));
      }

      $fieldset.find('.purchasePrice input')
        .addClass('auto')
        .val(mc.toFixed(purchasePrice, 2));

      mc.updateProfit($fieldset);
      mc.postItem($fieldset);
    },

    /*************************************************
    *  Called when cans per month is modified.
    *************************************************/
    onChangeCansPerMonth: function() {
      var $fieldset = $(this).parents('fieldset.marginCalculator');
      mc.updateProfit($fieldset);
      mc.postItem($fieldset);
    },

    /*************************************************
    *  Update the profit based on the specified margin.
    *************************************************/
    updateProfit: function($fieldset) {
      var marginValue = parseFloat($fieldset.find('.marginValue input.can').val());
      var cansPerMonth = parseInt($fieldset.find('input.cansPerMonth').val(), 10);

      if (isNaN(marginValue)) {
        $fieldset.find('.profit').hide();
      } else {
        $fieldset.find('.profit').show();
      }

      if (isNaN(marginValue) || isNaN(cansPerMonth)) {
        return false;
      }

      $fieldset.find('.yearProfit').text(mc.toFixed(cansPerMonth * marginValue * 12));
    },

    /*************************************************
    *  Post a CalculatorProduct for the next tim ethe user visits the page.
    *************************************************/
    postItem: function($fieldset) {
      var product ={
        ProductId: $fieldset.find('input.productId').val(),
        PurchasePrice: $fieldset.find('.purchasePrice input').val(),
        RollMargin: $fieldset.find('.marginValue input.roll').val(),
        CansPerMonth: $fieldset.find('input.cansPerMonth').val(),
        AutoPurchasePrice: $fieldset.find('.purchasePrice input').hasClass('auto'),
        AutoMarginValue: $fieldset.find('.marginValue input').hasClass('auto'),
        AutoMarginPercent: $fieldset.find('.marginPercent input').hasClass('auto'),
        AutoOtdPrice: $fieldset.find('.otdPrice input').hasClass('auto')
      };

      var loc = document.location;
      var url = loc.protocol + '//' + loc.host + loc.pathname + '?q=updateCalcProduct';
      $.post(url, {
        target: product.ProductId,
        item: $.toJSON(product)
      });
      return false;
    }
  };

  $(document).ready(function() {
    //    $('.roll').hide();
    $('.marginCalculator .profit').hide();

    $('.marginCalculator input.floatInput').keypress(mc.validateFloatOnKeypress);
    $('.marginCalculator input.intInput').keypress(mc.validateIntOnKeypress);

    $('.marginCalculator .purchasePrice input').keyup(mc.onChangePurchasePrice);
    $('.marginCalculator .marginValue input').keyup(mc.onChangeMargin);
    $('.marginCalculator .marginPercent input').keyup(mc.onChangeMarginPercent);
    $('.marginCalculator .otdPrice input').keyup(mc.onChangeOtdPrice);

    $('.marginCalculator input.cansPerMonth').keyup(mc.onChangeCansPerMonth);

    $('fieldset.marginCalculator').each(function() {mc.updateProfit($(this));});
  });
})();