/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

parcel Lucy;

/** Base class for composite Query objects.
 *
 * PolyQuery serves as a shared base class for
 * L<ANDQuery|Lucy::Search::ANDQuery>,
 * L<ORQuery|Lucy::Search::ORQuery>,
 * L<NOTQuery|Lucy::Search::NOTQuery>, and
 * L<RequiredOptionalQuery|Lucy::Search::RequiredOptionalQuery>.  All of
 * these classes may serve as nodes in composite Query with a tree structure
 * which may be walked.
 */
abstract class Lucy::Search::PolyQuery
    inherits Lucy::Search::Query : dumpable {

    VArray    *children;

    /**
     * @param children An array of child Queries.
     */
    public inert PolyQuery*
    init(PolyQuery *self, VArray *children = NULL);

    /** Add a child Query node.
     */
    public void
    Add_Child(PolyQuery *self, Query *query);

    void
    Set_Children(PolyQuery *self, VArray *children);

    VArray*
    Get_Children(PolyQuery *self);

    public void
    Serialize(PolyQuery *self, OutStream *outstream);

    public incremented PolyQuery*
    Deserialize(PolyQuery *self, InStream *instream);

    public bool_t
    Equals(PolyQuery *self, Obj *other);

    public void
    Destroy(PolyQuery *self);
}

class Lucy::Search::PolyCompiler inherits Lucy::Search::Compiler {

    VArray *children;

    inert incremented PolyCompiler*
    new(PolyQuery *parent, Searcher *searcher, float boost);

    /** Initialize the Compiler, creating a Compiler child for each child
     * Query.  Normalization is left to the subclass.
     */
    inert PolyCompiler*
    init(PolyCompiler *self, PolyQuery *parent, Searcher *searcher,
         float boost);

    public float
    Sum_Of_Squared_Weights(PolyCompiler *self);

    public void
    Apply_Norm_Factor(PolyCompiler *self, float factor);

    public incremented VArray*
    Highlight_Spans(PolyCompiler *self, Searcher *searcher,
                    DocVector *doc_vec, const CharBuf *field);

    public void
    Destroy(PolyCompiler *self);

    public void
    Serialize(PolyCompiler *self, OutStream *outstream);

    public incremented PolyCompiler*
    Deserialize(PolyCompiler *self, InStream *instream);
}


