'use strict';

var DataError = require('./errors/DataError');
var cmp = require('./cmp');
var validateKey = require('./validateKey');

// http://www.w3.org/TR/2015/REC-IndexedDB-20150108/#range-concept
function FDBKeyRange() {
    this.lower = undefined;
    this.upper = undefined;
    this.lowerOpen = undefined;
    this.upperOpen = undefined;

    this.toString = function () {
        return '[object IDBKeyRange]';
    };
}

FDBKeyRange.only = function (value) {
    if (value === undefined) { throw new TypeError(); }
    validateKey(value);
    var keyRange = new FDBKeyRange();
    keyRange.lower = value;
    keyRange.upper = value;
    keyRange.lowerOpen = false;
    keyRange.upperOpen = false;
    return keyRange;
};

FDBKeyRange.lowerBound = function (lower, open) {
    if (lower === undefined) { throw new TypeError(); }
    validateKey(lower);
    var keyRange = new FDBKeyRange();
    keyRange.lower = lower;
    keyRange.lowerOpen = open === true ? true : false;
    keyRange.upperOpen = true;
    return keyRange;
};

FDBKeyRange.upperBound = function (upper, open) {
    if (upper === undefined) { throw new TypeError(); }
    validateKey(upper);
    var keyRange = new FDBKeyRange();
    keyRange.upper = upper;
    keyRange.lowerOpen = true;
    keyRange.upperOpen = open === true ? true : false;
    return keyRange;
};

FDBKeyRange.bound = function (lower, upper, lowerOpen, upperOpen) {
    if (lower === undefined || upper === undefined) { throw new TypeError(); }

    var cmpResult = cmp(lower, upper);
    if (cmpResult === 1 || (cmpResult === 0 && (lowerOpen || upperOpen))) {
        throw new DataError();
    }

    validateKey(lower);
    validateKey(upper);
    var keyRange = new FDBKeyRange();
    keyRange.lower = lower;
    keyRange.upper = upper;
    keyRange.lowerOpen = lowerOpen === true ? true : false;
    keyRange.upperOpen = upperOpen === true ? true : false;
    return keyRange;
};


FDBKeyRange.check = function (keyRange, key) {
    var cmpResult;
    if (keyRange.lower !== undefined) {
        cmpResult = cmp(keyRange.lower, key);

        if (cmpResult === 1 || (cmpResult === 0 && keyRange.lowerOpen)) {
            return false;
        }
    }
    if (keyRange.upper !== undefined) {
        cmpResult = cmp(keyRange.upper, key);

        if (cmpResult === -1 || (cmpResult === 0 && keyRange.upperOpen)) {
            return false;
        }
    }
    return true;
};

module.exports = FDBKeyRange;