function stPrice() {}

function stPriceTaxManagment(params)
{
   this.initialize = function(params)
   {
      this.priceFields = [];

      this.addParams = params.params;

      if (params.taxField != undefined)
      {
         this.taxField = $(params.taxField);

         this.taxField.observe('change', this.taxFieldListener.bind(this));

         this.taxValues = params.taxValues;
      }
      else if (params.taxValue != undefined)
      {
         this.taxValue = params.taxValue;
      }
      else
      {
         throw "Missing parameters {taxField: field_id, taxValues: [value1, value2, ...]} or {taxValue: value}";
      }

      this.params = params;

      params.priceFields.each(this.initializePriceField.bind(this));
   }

   this.addPriceField = function(field)
   {
      var index = this.priceFields.length;

      this.initializePriceField(field, index);
   }

   this.disablePriceFields = function()
   {
      this.priceFields.each(function (f)
      {
         f.price.disable();
      });
   }

   this.enablePriceFields = function()
   {
      this.priceFields.each(function (f)
      {
         f.price.enable();
      });
   }

   this.disablePriceWithTaxFields = function()
   {
      this.priceFields.each(function (f)
      {
         f.priceWithTax.disable();
      });
   }

   this.refreshPriceFields = function()
   {
      var instance = this;

      this.priceFields.each(function (f)
      {
         instance.updatePriceByPriceWithTaxField(f.price, f.priceWithTax);
      });
   }

   this.refreshPriceWithTaxFields = function()
   {
      var instance = this;

      this.priceFields.each(function (f)
      {
         instance.updatePriceWithTaxByPriceField(f.price, f.priceWithTax);
      });
   }

   this.enablePriceWithTaxFields = function()
   {
      this.priceFields.each(function (f)
      {
         f.priceWithTax.enable();
      });
   }

   this.initializePriceField = function(fields, index)
   {
      if (!$(fields.price))
      {
         window.alert('Field "'+fields.price+'" does not exist');
      }      
      
      fields.price = $(fields.price);
      
      if (!$(fields.priceWithTax))
      {
         window.alert('Field "'+fields.priceWithTax+'" does not exist');
      }          
      
      fields.priceWithTax = $(fields.priceWithTax);

      fields.price.dependency = fields.priceWithTax;

      fields.priceWithTax.dependency = fields.price;

      fields.price.observe('change', this.priceFieldListener.bind(this));

      fields.priceWithTax.observe('change', this.priceWithTaxFieldListener.bind(this));

      fields.price.observe('keypress', this.priceFieldListener.bind(this));

      fields.priceWithTax.observe('keypress', this.priceWithTaxFieldListener.bind(this));

      this.priceFields[index] = fields;
   }

   this.updatePriceWithTaxByPriceField = function(priceField, priceWithTaxField)
   {
      priceField.value = stPrice.fixNumberFormat(priceField.value);

      var price = stPrice.calculate(priceField.value, this.currentTaxValue());

      stPrice.updateField(priceWithTaxField, price);
   }

   this.updatePriceByPriceWithTaxField = function(priceField, priceWithTaxField)
   {
      priceWithTaxField.value = stPrice.fixNumberFormat(priceWithTaxField.value);
      
      var price = stPrice.extract(priceWithTaxField.value, this.currentTaxValue());

      stPrice.updateField(priceField, price);
   }

   this.taxFieldListener = function()
   {
      var instance = this;

      this.priceFields.each(function (f)
      {
         if (f.price.disabled == false)
         {
            instance.updatePriceWithTaxByPriceField(f.price, f.priceWithTax);

            if (instance.params.onChange)
            {
               instance.params.onChange(f.price, f.priceWithTax, this.taxField, this.addParams);
            }
         }
      });
   }

   this.priceFieldListener = function(event)
   {
      if (event.type == 'change' ||  event.type == 'keypress' && event.keyCode == 13)
      {
//         Event.stop(event);

         var priceField = event.element();

         this.updatePriceWithTaxByPriceField(priceField, priceField.dependency);

         if (this.params.onChange)
         {
            this.params.onChange(priceField, priceField.dependency, this.taxField, this.addParams);
         }
      }
   }

   this.priceWithTaxFieldListener = function(event)
   {
      if (event.type == 'change' ||  event.type == 'keypress' && event.keyCode == 13)
      {
//         Event.stop(event);

         var priceField = event.element();

         this.updatePriceByPriceWithTaxField(priceField.dependency, priceField);

         if (this.params.onChange)
         {
            this.params.onChange(priceField.dependency, priceField, this.taxField, this.addParams);
         }
      }
   }

   this.currentTaxValue = function()
   {
      return this.taxValue != undefined ? this.taxValue : this.taxValues[this.taxField.selectedIndex];
   }

   this.initialize(params);
}

stPrice.updateField = function(field, value, update_disabled)
{
   field = $(field);

   if ((field.disabled == false || update_disabled) && field.value != value)
   {
      field.value = value;

      var prev_color = field.readAttribute('prev-background-color');

      if (!prev_color)
      {
         prev_color = field.getStyle('background-color');

         field.setAttribute('prev-background-color', prev_color);
      }

      new Effect.Highlight(field, {
         startcolor: '#ffff99',
         endcolor: prev_color.parseColor(),
         restorecolor: prev_color.parseColor(),
         duration: 0.8
      });
   }
}

stPrice.calculate = function(price, tax)
{
   return stPrice.round(price * (1 + tax * 0.01));
}

stPrice.applyExchange = function(price, exchange)
{
   return price / exchange;
}

stPrice.extractExchange = function(price, exchange)
{
   return price * exchange;
}

stPrice.extract = function(price_with_tax, tax)
{
   return stPrice.round(price_with_tax / (1 + tax * 0.01));
}

stPrice.applyDiscount = function(price, discount)
{
   return stPrice.round(price * (1 - discount * 0.01));
}

stPrice.round = function(price, precision)
{
   var n = new Number(price);

   return n.toFixed(precision != undefined ? precision : 2);
}

stPrice.fixNumberFormat = function(number, precision, maxlength)
{
   if (maxlength == undefined)
   {
      maxlength = 11;
   }
   
   number = number.replace(',', '.');

   number = number.split('.', 2);
   
   number[0] = number[0].slice(0, maxlength-3);

   number = number.join('.').replace(/[^0-9\.]/ig,'');

   return stPrice.round(number, precision);
}

stPrice.addFormatBehavior = function(field, precision, maxlength)
{
   $(field).observe('change', function() {
      this.value = stPrice.fixNumberFormat(this.value, precision, maxlength);
   });
}
