var Node = require(“./node”),

Element = require("./element");

var Selector = function (elements, extendList, condition, index, currentFileInfo, visibilityInfo) {

this.elements = elements;
this.extendList = extendList;
this.condition = condition;
this.currentFileInfo = currentFileInfo || {};
if (!condition) {
    this.evaldCondition = true;
}
this.copyVisibilityInfo(visibilityInfo);

}; Selector.prototype = new Node(); Selector.prototype.type = “Selector”; Selector.prototype.accept = function (visitor) {

if (this.elements) {
    this.elements = visitor.visitArray(this.elements);
}
if (this.extendList) {
    this.extendList = visitor.visitArray(this.extendList);
}
if (this.condition) {
    this.condition = visitor.visit(this.condition);
}

}; Selector.prototype.createDerived = function(elements, extendList, evaldCondition) {

var info = this.visibilityInfo();
evaldCondition = (evaldCondition != null) ? evaldCondition : this.evaldCondition;
var newSelector = new Selector(elements, extendList || this.extendList, null, this.index, this.currentFileInfo, info);
newSelector.evaldCondition = evaldCondition;
newSelector.mediaEmpty = this.mediaEmpty;
return newSelector;

}; Selector.prototype.createEmptySelectors = function() {

var el = new Element('', '&', this.index, this.currentFileInfo),
    sels = [new Selector([el], null, null, this.index, this.currentFileInfo)];
sels[0].mediaEmpty = true;
return sels;

}; Selector.prototype.match = function (other) {

var elements = this.elements,
    len = elements.length,
    olen, i;

other.CacheElements();

olen = other._elements.length;
if (olen === 0 || len < olen) {
    return 0;
} else {
    for (i = 0; i < olen; i++) {
        if (elements[i].value !== other._elements[i]) {
            return 0;
        }
    }
}

return olen; // return number of matched elements

}; Selector.prototype.CacheElements = function() {

if (this._elements) {
    return;
}

var elements = this.elements.map( function(v) {
    return v.combinator.value + (v.value.value || v.value);
}).join("").match(/[,&#\*\.\w-]([\w-]|(\\.))*/g);

if (elements) {
    if (elements[0] === "&") {
        elements.shift();
    }
} else {
    elements = [];
}

this._elements = elements;

}; Selector.prototype.isJustParentSelector = function() {

return !this.mediaEmpty &&
    this.elements.length === 1 &&
    this.elements[0].value === '&' &&
    (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === '');

}; Selector.prototype.eval = function (context) {

var evaldCondition = this.condition && this.condition.eval(context),
    elements = this.elements, extendList = this.extendList;

elements = elements && elements.map(function (e) { return e.eval(context); });
extendList = extendList && extendList.map(function(extend) { return extend.eval(context); });

return this.createDerived(elements, extendList, evaldCondition);

}; Selector.prototype.genCSS = function (context, output) {

var i, element;
if ((!context || !context.firstSelector) && this.elements[0].combinator.value === "") {
    output.add(' ', this.currentFileInfo, this.index);
}
if (!this._css) {
    //TODO caching? speed comparison?
    for (i = 0; i < this.elements.length; i++) {
        element = this.elements[i];
        element.genCSS(context, output);
    }
}

}; Selector.prototype.getIsOutput = function() {

return this.evaldCondition;

}; module.exports = Selector;