/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.xmlbeans.impl.store;

import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaTypeLoader;
import org.apache.xmlbeans.XmlDocumentProperties;
import org.apache.xmlbeans.XmlOptions;
import org.w3c.dom.Node;

import javax.xml.namespace.QName;
import java.util.ArrayList;

final class DomSaver extends Saver {
    private Cur _nodeCur;
    private SchemaType _type;
    private final SchemaTypeLoader _stl;
    private final XmlOptions _options;
    private final boolean _isFrag;


    DomSaver(Cur c, boolean isFrag, XmlOptions options) {
        super(c, options);

        if (c.isUserNode()) {
            _type = c.getUser().get_schema_type();
        }

        _stl = c._locale._schemaTypeLoader;
        _options = options;
        _isFrag = isFrag;
    }

    Node saveDom() {
        Locale l = Locale.getLocale(_stl, _options);

        l.enter();

        try {
            _nodeCur = l.getCur();  // Not weak or temp

            // Build the tree

            //noinspection StatementWithEmptyBody
            while (process());

            // Set the type

            while (!_nodeCur.isRoot()) {
                _nodeCur.toParent();
            }

            if (_type != null) {
                _nodeCur.setType(_type);
            }

            Node node = (Node) _nodeCur.getDom();

            _nodeCur.release();

            _nodeCur = null;

            return node;
        } finally {
            l.exit();
        }
    }

    protected boolean emitElement(SaveCur c, ArrayList attrNames, ArrayList attrValues) {
        // If there was text or comments before the frag element, I will loose them -- oh well
        // Also, I will lose any attributes and namesapces on the fragment -- DOM can
        // have attrs in fragments

        if (Locale.isFragmentQName(c.getName())) {
            _nodeCur.moveTo(null, Cur.NO_POS);
        }

        ensureDoc();

        _nodeCur.createElement(getQualifiedName(c, c.getName()));
        _nodeCur.next();

        for (iterateMappings(); hasMapping(); nextMapping()) {
            _nodeCur.createAttr(_nodeCur._locale.createXmlns(mappingPrefix()));
            _nodeCur.next();
            _nodeCur.insertString(mappingUri());
            _nodeCur.toParent();
            _nodeCur.skipWithAttrs();
        }

        for (int i = 0; i < attrNames.size(); i++) {
            _nodeCur.createAttr(getQualifiedName(c, (QName) attrNames.get(i)));
            _nodeCur.next();
            _nodeCur.insertString((String) attrValues.get(i));
            _nodeCur.toParent();
            _nodeCur.skipWithAttrs();
        }

        return false;
    }

    protected void emitFinish(SaveCur c) {
        if (!Locale.isFragmentQName(c.getName())) {
            assert _nodeCur.isEnd();
            _nodeCur.next();
        }
    }

    protected void emitText(SaveCur c) {
        ensureDoc();

        Object src = c.getChars();

        if (c._cchSrc > 0) {
            _nodeCur.insertChars(src, c._offSrc, c._cchSrc);
            _nodeCur.next();
        }
    }

    protected void emitComment(SaveCur c) {
        ensureDoc();

        _nodeCur.createComment();
        emitTextValue(c);
        _nodeCur.skip();
    }

    protected void emitProcinst(SaveCur c) {
        ensureDoc();

        _nodeCur.createProcinst(c.getName().getLocalPart());
        emitTextValue(c);
        _nodeCur.skip();
    }

    protected void emitDocType(String docTypeName, String publicId, String systemId) {
        ensureDoc();

        XmlDocumentProperties props = Locale.getDocProps(_nodeCur, true);
        props.setDoctypeName(docTypeName);
        props.setDoctypePublicId(publicId);
        props.setDoctypeSystemId(systemId);
    }

    protected void emitStartDoc(SaveCur c) {
        ensureDoc();
    }

    protected void emitEndDoc(SaveCur c) {
    }

    private QName getQualifiedName(SaveCur c, QName name) {
        String uri = name.getNamespaceURI();

        String prefix = uri.length() > 0 ? getUriMapping(uri) : "";

        if (prefix.equals(name.getPrefix())) {
            return name;
        }

        return _nodeCur._locale.makeQName(uri, name.getLocalPart(), prefix);
    }

    private void emitTextValue(SaveCur c) {
        c.push();
        c.next();

        if (c.isText()) {
            _nodeCur.next();
            _nodeCur.insertChars(c.getChars(), c._offSrc, c._cchSrc);
            _nodeCur.toParent();
        }

        c.pop();
    }

    private void ensureDoc() {
        if (!_nodeCur.isPositioned()) {
            if (_isFrag) {
                _nodeCur.createDomDocFragRoot();
            } else {
                _nodeCur.createDomDocumentRoot();
            }

            _nodeCur.next();
        }
    }

}

