  var WINDOW_WIDTH = 320;
  var WINDOW_HEIGHT = 140;
  var WINDOW_CAPTION = 'Warning';

  var MIN_QUANTITY = 1;
  var MAX_QUANTITY = 99999999;

  var CORRECT_QUANTITY = 0;
  var INCORRECT_QUANTITY = 1;
  var SMALL_QUANTITY = 2;
  var LARGE_QUANTITY = 3;

  function checkQuantity() {
    if (this.quantity == null) {
      return INCORRECT_QUANTITY;
    }
    if (this.quantity < this.minQuantity) {
      return SMALL_QUANTITY;
    }
    if (this.maxQuantity != null) {
      if (this.quantity > this.maxQuantity) {
        return LARGE_QUANTITY;
      }
    }
    if ((this.quantityInterval != null)&&(this.quantityInterval != 0)) {
      var checkValue = Math.round((this.quantity-this.minQuantity)*100000000 ) % (this.quantityInterval*100000000);
      if ( checkValue != 0) {
        return INCORRECT_QUANTITY;
      }
    }
    return CORRECT_QUANTITY;
  }

  function getCorrectedQuantity(checkResult) {
    if (checkResult == SMALL_QUANTITY) {
      return this.minQuantity;
    } else if (checkResult == LARGE_QUANTITY) {
      return this.maxQuantity;
    }
  }

  function validate(incorrectMsg, smallMsg, largeMsg) {
    var checkResult = this.checkQuantity();
    if (checkResult != CORRECT_QUANTITY) {
      var message = "";
      if (checkResult == INCORRECT_QUANTITY) {
        message = incorrectMsg;
      } else if (checkResult == SMALL_QUANTITY) {
        message = smallMsg;
      } else if (checkResult == LARGE_QUANTITY) {
        message = largeMsg;
      }
      alert(message);
      return false;
    }
    return true;
  }

  function Product(sn, selected, quantity, minQuantity, maxQuantity, quantityInterval, canBeAddedToCart) {
    this.sn = sn;
    this.selected = selected;
    this.quantity = quantity;
    this.minQuantity = minQuantity!=null ? minQuantity : MIN_QUANTITY;
    this.maxQuantity = maxQuantity!=null ? maxQuantity : MAX_QUANTITY;
    this.quantityInterval = quantityInterval;
    this.checkQuantity = checkQuantity;
    this.getCorrectedQuantity = getCorrectedQuantity;
    this.validate = validate;
    if (canBeAddedToCart != null) {
      this.canBeAddedToCart = canBeAddedToCart;
    } else {
      this.canBeAddedToCart = true;
    }
    return this;
  }

  function findProduct(sn) {
    for (var i = 0; i < this.products.length; i++)
      if (sn == this.products[i].sn)
        return this.products[i];
    return null;
  }

  function addProduct(p) {
    this.products[this.products.length] = p;
  }

  function createProductSNList(forCart) {
    var result = "";
    for (var i = 0; i < this.products.length; i++) {
      if (this.products[i].selected) {
        if (forCart) {
          if (this.products[i].canBeAddedToCart) {
            result += this.products[i].sn + ";";
          }
        } else {
          result += this.products[i].sn + ";";
        }
      }
    }
    if (result.length > 0)
      result = result.substr(0, result.length - 1);
    return result;
  }

  function createProductQuantityList(forCart) {
    var result = "";
    for (var i = 0; i < this.products.length; i++) {
      if (this.products[i].selected) {
        if (forCart) {
          if (this.products[i].canBeAddedToCart) {
            result += this.products[i].quantity + ";";
          }
        } else {
          result += this.products[i].quantity + ";";
        }
      }
    }
    if (result.length > 0)
      result = result.substr(0, result.length - 1);
    return result;
  }

  function createCartProductSNList() {
    return this.createProductSNList(true);
  }

  function createCartProductQuantityList() {
    return this.createProductQuantityList(true);
  }

  function setSelected(sn, selected) {
    var p = this.findProduct(sn);
    if (p)
      p.selected = selected;
  }

  function selectAll() {
    for (var i = 0; i < this.products.length; i++)
      this.products[i].selected = true;
  }

  function invertAll() {
    for (var i = 0; i < this.products.length; i++)
      this.products[i].selected = !this.products[i].selected;
  }

  function deselectAll() {
    for (var i = 0; i < this.products.length; i++)
      this.products[i].selected = false;
  }

  function validateProductList(incorrectMsg, smallMsg, largeMsg) {
    var alwaysIncrease = false;
    var alwaysDecrease = false;
    var correctedQuantities = new Array();

    // checking quantities
    for (var i = 0; i < this.products.length; i++) {
      if (this.products[i].selected && this.products[i].canBeAddedToCart) {
        correctedQuantities[i] = this.products[i].quantity;
        var checkResult = this.products[i].checkQuantity();
        if (checkResult == INCORRECT_QUANTITY) {
          alert(incorrectMsg);
          return false;
        } else if (checkResult == SMALL_QUANTITY) {
          if (!alwaysIncrease) {
            if (confirm(smallMsg)) {
              alwaysIncrease = true;
            } else {
              return false;
            }
          }
          if (alwaysIncrease) {
            correctedQuantities[i] = this.products[i].minQuantity;
          }
        } else if (checkResult == LARGE_QUANTITY) {
          if (!alwaysDecrease) {
            if (confirm(largeMsg)) {
              alwaysDecrease = true;
            } else {
              return false;
            }
          }
          if (alwaysDecrease) {
            correctedQuantities[i] = this.products[i].maxQuantity;
          }
        }
      }
    }
    // correcting quantities
    for (var i = 0; i < this.products.length; i++) {
      if (this.products[i].selected && this.products[i].canBeAddedToCart) {
        this.products[i].quantity = correctedQuantities[i];
      }
    }

    return true;
  }

  // count of selectedd products
  function countOfSelected() {
    var count = 0;
    for (var i = 0; i < this.products.length; i++)
      if (this.products[i].selected) count++;
    return count;
  }

  function ProductList(increaseMessage, decreaseMessage, cancelMessage) {
    this.products = new Array();
    this.increaseMessage = increaseMessage;
    this.decreaseMessage = decreaseMessage;
    this.cancelMessage = cancelMessage;
    this.findProduct = findProduct;
    this.addProduct = addProduct;
    this.createProductSNList = createProductSNList;
    this.createProductQuantityList = createProductQuantityList;
    this.createCartProductSNList = createCartProductSNList;
    this.createCartProductQuantityList = createCartProductQuantityList;
    this.setSelected = setSelected;
    this.selectAll = selectAll;
    this.invertAll = invertAll;
    this.deselectAll = deselectAll;
    this.countOfSelected = countOfSelected; // count of selectedd products
    this.validate = validateProductList;
    return this;
  }

