/*
 * 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.
 */

package freemarker.debug;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.Date;

import freemarker.template.TemplateModelException;

/**
 * Represents the debugger-side mirror of a TemplateModel object, a Template
 * object, or a Configuration object. The Environment objects are also represented
 * by instances of this model, although not directly but through a separate
 * subinterface {@link DebuggedEnvironment}. The interface is a union of
 * almost all of FreeMarker template models with identical method signatures.
 * For purposes of optimizing network traffic there are bulk retrieval methods
 * for sequences and hashes, as well as a {@link #getModelTypes()} method that
 * returns a bit mask of various {@code TYPE_xxx} constants flagging which
 * template models are implemented by the mirrored object.
 */
public interface DebugModel extends Remote {
    public static final int TYPE_SCALAR        =    1;
    public static final int TYPE_NUMBER        =    2;
    public static final int TYPE_DATE          =    4;
    public static final int TYPE_BOOLEAN       =    8;
    public static final int TYPE_SEQUENCE      =   16;
    public static final int TYPE_COLLECTION    =   32;
    public static final int TYPE_HASH          =   64;
    public static final int TYPE_HASH_EX       =  128;
    public static final int TYPE_METHOD        =  256;
    public static final int TYPE_METHOD_EX     =  512;
    public static final int TYPE_TRANSFORM     = 1024;
    public static final int TYPE_ENVIRONMENT   = 2048;
    public static final int TYPE_TEMPLATE      = 4096;
    public static final int TYPE_CONFIGURATION = 8192;
    
    public String getAsString()
    throws TemplateModelException,
        RemoteException;
        
    public Number getAsNumber()
    throws TemplateModelException,
        RemoteException;
    
    public boolean getAsBoolean()
    throws TemplateModelException,
        RemoteException;
    
    public Date getAsDate()
    throws TemplateModelException,
        RemoteException;
    
    public int getDateType()
    throws TemplateModelException,
        RemoteException;
        
    public int size()
    throws TemplateModelException,
        RemoteException;
        
    public DebugModel get(int index)
    throws TemplateModelException,
        RemoteException;
    
    public DebugModel[] get(int fromIndex, int toIndex)
    throws TemplateModelException,
        RemoteException;
        
    public DebugModel get(String key)
    throws TemplateModelException,
        RemoteException;
        
    public DebugModel[] get(String[] keys)
    throws TemplateModelException,
        RemoteException;
    
    public DebugModel[] getCollection()
    throws TemplateModelException,
        RemoteException;

    public String[] keys()
    throws TemplateModelException,
        RemoteException;
    
    public int getModelTypes()
    throws RemoteException;
}
