/********************************************************************
*                        Range Class Definition                     *
/********************************************************************
* The Range class is a model for data working with TAC slider.      *
* Based on the ideas of the javax.swing.DefaultBoundedRangeModel.   *   
* URL: http://developer.classpath.org/doc/javax/swing/              *
* DefaultBoundedRangeModel-source.html                              *
********************************************************************/

function Range() {
    this._value = 0;
    this._minimum = 0;
    this._maximum = 100;
    this._extent = 0;
    this._isAdjusting = 0;
}

Range.prototype.hasOwnProperty = function (name) {
    switch (name) {
        case "toString":
        case "valueOf":
            return true;
        default:
            return false;
    }
};

Range.prototype.valueOf = function() {
    return this._value;
};

Range.prototype.toString = function () {
    return "Range [value=" + this._value
            + ", extent=" + this._extent
            + ", minimum=" + this._minimum
            + ", maximum=" + this._maximum
            + ", isAdjusting=" + this._isAdjusting
            + ']';  
};

Range.prototype.setRangeProperties = function (value,  
                                               extent, 
                                               minimum, 
                                               maximum, 
                                               isAdjusting) {

    // validate
    value = parseInt(value);
    extent = parseInt(extent);
    minimum = parseInt(minimum);
    maximum = parseInt(maximum);
    isAdjusting = parseInt(isAdjusting);

    if (isNaN(value) 
        || isNaN(extent) 
        || isNaN(minimum) 
        || isNaN(maximum)
        || isNaN(isAdjusting)) 
        return;
    
    minimum = Math.min(Math.min(minimum, maximum), value);
    maximum = Math.max(value, maximum);
    if (extent + value > maximum)
        extent = maximum - value;
    extent = Math.max(0, extent);
    
    if ((value == this._value) 
        && (extent == this._extent)
        && (minimum == this._minimum)
        && (maximum == this._maximum)
        && (isAdjusting == this._isAdjusting))
        return;

    this._value = value;
    this._extent = extent;
    this._minimum = minimum;
    this._maximum = maximum;
    this._isAdjusting = isAdjusting;

    if (!this._isAdjusting && typeof this.onchange == "function") {
        this.onchange();
    }

};

Range.prototype.getValue = function() {
        return this.valueOf();
};

Range.prototype.setValue = function (value) {
    // validate
    value = parseInt(value);
    if (isNaN(value)) return;
    
    value = Math.max(this._minimum,value);
    if (value + this._extent > this._maximum)
        value = this._maximum - this._extent;
        
    if (this._value != value) {
        this._value = value;
        if (!this._isAdjusting && typeof this.onchange == "function") {
            this.onchange();
        }       
    }
        
};

Range.prototype.getValue = function () {
    return parseInt(this._value);
};

Range.prototype.setExtent = function (extent) {
    // validate
    extent = parseInt(extent);
    if (isNaN(extent)) return;
    extent = Math.max(extent,0);
    if (this._value + extent > this._maximum) 
        extent = this._maximum - this._value;

    if (this._extent != extent) {
        this._extent = extent;
        if (!this._isAdjusting && typeof this.onchange == "function") {
            this.onchange();
        }
    }
};

Range.prototype.getExtent = function () {
    return parseInt(this._extent);
};

Range.prototype.setMinimum = function (minimum) {
    // validate
    minimum = parseInt(minimum);
    if (isNaN(minimum)) return;

    var maximum = Math.max(minimum, this._maximum);
    var value = Math.max(minimum, this._value);

    this.setRangeProperties(value, this._extent, minimum, maximum, this._isAdjusting);

};

Range.prototype.getMinimum = function () {
    return parseInt(this._minimum);
};

Range.prototype.setMaximum = function (maximum) {
    // validate
    maximum = parseInt(maximum);
    if (isNaN(maximum)) return;

    var minimum = Math.min(this._minimum, maximum);
    var extent = Math.min(this._extent, maximum - minimum);
    var value = Math.min(this._value, maximum - extent);

    this.setRangeProperties(value, extent, minimum, maximum, this._isAdjusting);

};

Range.prototype.getMaximum = function () {
    return parseInt(this._maximum);
};
