/*
Copyright (C) 2000-2010  Ministere de la culture et de la communication (France), AJLSM
See LICENCE file
*/
package fr.gouv.culture.sdx.pipeline;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

public class ElementFilter extends TagFilter {

    protected boolean _withinFilteredElement = false;
    protected int _filteredCount = 0;

    public void startElement(String uri, String loc, String raw, Attributes a)
            throws SAXException {
        setCurrentElementProperties(uri, loc, raw, a);
        boolean send = shouldSendElementEvent(uri, loc, raw, a);
        if (send == super._send)
            this._filteredCount++;
        if (send) {
            if (super.xmlConsumer != null)
                super.xmlConsumer.startElement(uri, loc, raw, a);
        }
    }

    public void characters(char c[], int start, int len)
            throws SAXException {
        boolean send = shouldSendElementEvent(c_uri, c_loc, c_raw, super.peekCurrentAttributes());
        if (send) {
            if (super.xmlConsumer != null)
                super.xmlConsumer.characters(c, start, len);
        }
    }

    public void endElement(String uri, String loc, String raw)
            throws SAXException {
        boolean send = shouldSendElementEvent(uri, loc, raw, super.peekCurrentAttributes());
        if (send == super._send) {
            this._filteredCount--;
            if (this._filteredCount == 0)
                this._withinFilteredElement = false;
        }
        if (send) {
            if (super.xmlConsumer != null)
                super.xmlConsumer.endElement(uri, loc, raw);
        }
        resetCurrentElementProperties(uri, loc, raw);
    }


    protected boolean shouldSendElementEvent(String uri, String loc, String raw, Attributes a) {
        boolean send = super.shouldSendElementEvent(uri, loc, raw, a);
        return withinFilteredElement(send);
    }


    protected boolean withinFilteredElement(boolean shouldSendElementEvent) {
        boolean send = shouldSendElementEvent;
        if (shouldSendElementEvent == super._send)
            this._withinFilteredElement = true;
        if (this._withinFilteredElement == true || this._filteredCount > 0)
            send = super._send;

        return send;
    }

    protected void resetFields() {
        super.resetFields();
        _withinFilteredElement = false;
        _filteredCount = 0;
    }

    public void recycle() {
        super.recycle();
        this.resetFields();
    }
}
