﻿var extendedSlider = (function ($) {

  function _getMatchingInterval(intervals, value, isAlteredValue) {
    var result = null;

    $.each(intervals, function (i, e) {
      var normalizaedValue;

      normalizaedValue = isAlteredValue ? value : _getProRatedValue(e.outputValues, e.boundaries, value);
      if (e.boundaries.from <= normalizaedValue && e.boundaries.to >= normalizaedValue) {
        result = e;
        return false;
      }
    });

    return result;
  }

  function _roundToStep(value, step) {
    return value - (value % step) + ((value % step) < step / 2 ? 0 : step);
  }

  function _invokeSlideEvent($slider) {
    var event, ui;

    event = {};
    ui = { value: parseFloat($slider.slider('option', 'value')), handle: $slider.slider('option', 'handle') };

    $slider.slider('option', 'slide')(event, ui);
  }

  function _test() {
    function _testRoundToStep() {
      var value, step, expectedValue, actualValue;

      // Test 1
      value = 1220;
      step = 50;
      expectedValue = 1200;
      actualValue = _roundToStep(value, step);

      console.log(actualValue === expectedValue ? 'Test passed successfully' : 'Test failed');

      // Test 2
      value = 1225;
      step = 50;
      expectedValue = 1250;
      actualValue = _roundToStep(value, step);

      console.log(actualValue === expectedValue ? 'Test passed successfully' : 'Test failed');

      // Test 3
      value = 1250;
      step = 50;
      expectedValue = 1250;
      actualValue = _roundToStep(value, step);

      console.log(actualValue === expectedValue ? 'Test passed successfully' : 'Test failed');
    }

    _testRoundToStep();
  }

  function _getProRatedValue(sourceBoundaries, targetBoundaries, value) {
    return targetBoundaries.from + (targetBoundaries.to - targetBoundaries.from) * (value - sourceBoundaries.from) / (sourceBoundaries.to - sourceBoundaries.from);
  }

  $.fn.extendSlider = function (options) {
    $(this).each(function () {
      var $slider = $(this),
          originalActions = {};

      originalActions.slide = $slider.slider('option', 'slide');
      $slider.slider('option', 'slide', function (event, ui) {
        var matchingInterval = _getMatchingInterval(options.intervals, ui.value, $slider.data('isAlterateValue'));
        if (matchingInterval !== null) {
          if (!$slider.data('isAlterateValue')) {
            ui.value = _getProRatedValue(matchingInterval.outputValues, matchingInterval.boundaries, ui.value);
            $slider.slider('option', 'value', ui.value);
          }
          ui.interval = matchingInterval;
          ui.visibleValue = _getProRatedValue(matchingInterval.boundaries, matchingInterval.visibleValues, ui.value);
          ui.outputValue = _roundToStep(_getProRatedValue(matchingInterval.boundaries, matchingInterval.outputValues, ui.value), options.step);
          ui.units = matchingInterval.units[0];
          $slider.data('isAlterateValue', true);
        }
        if ($.isFunction(originalActions.slide)) { originalActions.slide(event, ui); }
      });

      //Calling the newly created handler
      _invokeSlideEvent($slider);
    });
  };

  return {
    test: _test,
    invokeSlideEvent: _invokeSlideEvent
  };

})(jQuery);

