package org.trinitydesktop.DCOP;


import java.io.*;


public class Stub
{
    private String _app, _obj;
    private int _status;
    private Client _client;

    public Stub(String app, String obj)
    {
	_app = app;
	_obj = obj;
	_status = 0;

	// TODO: The client should be shared between stubs.
	_client = new Client();
	_client.attach();
    }

    public String app()
    {
	return _app;
    }

    public String obj()
    {
	return _obj;
    }


    public Client client()
    {
	return _client;
    }


    public final static int CallFailed    = 0;
    public final static int CallSucceeded = 1;

    public int status()
    {
	return _status;
    }

    public void setStatus(int status)
    {
	_status = status;
    }

    public boolean ok()
    {
	return _status == CallSucceeded;
    }

    public void callFailed()
    {
	_status = CallFailed;
    }


    // accessor methods for the datatypes used ---------------------------

    protected boolean read_bool(DataInputStream is) throws IOException
    {
	return is.readBoolean();
    }

    protected void write_bool(DataOutputStream os, boolean val) throws IOException
    {
	os.writeBoolean(val);
    }

    protected short read_short_int(DataInputStream is) throws IOException
    {
	return is.readShort();
    }

    protected void write_short_int(DataOutputStream os, short val) throws IOException
    {
	os.writeShort(val);
    }

    protected int read_int(DataInputStream is) throws IOException
    {
	return is.readInt();
    }

    protected void write_int(DataOutputStream os, int val) throws IOException
    {
	os.writeInt(val);
    }

    protected int read_long_int(DataInputStream is) throws IOException
    {
	return is.readInt();
    }

    protected void write_long_int(DataOutputStream os, int val) throws IOException
    {
	os.writeInt(val);
    }

    protected float read_float(DataInputStream is) throws IOException
    {
	return is.readFloat();
    }

    protected void write_float(DataOutputStream os, float val) throws IOException
    {
	os.writeFloat(val);
    }

    protected double read_double(DataInputStream is) throws IOException
    {
	return is.readDouble();
    }

    protected void write_double(DataOutputStream os, double val) throws IOException
    {
	os.writeDouble(val);
    }

    protected String read_QString(DataInputStream is) throws IOException
    {
	int len = is.readInt();
	if (len == 0xffffffff)
	    return new String();
	else
	    {
		StringBuffer b = new StringBuffer();
		for (int i=0; i<len/2; ++i)
		    b.append(is.readChar());
		return b.toString();
	    }
    }

    protected void write_QString(DataOutputStream os, String val) throws IOException
    {
	os.writeInt(val.length()*2);
	for (int i=0; i<val.length(); ++i)
	    os.writeChar(val.charAt(i));
    }

    protected String read_QCString(DataInputStream is) throws IOException
    {
	int len = is.readInt();
	StringBuffer b = new StringBuffer();
	for (int i=0; i<len; ++i)
	    b.append((char)is.readByte());
	return b.toString();
    }

    protected void write_QCString(DataOutputStream os, String val) throws IOException
    {
	os.writeInt(val.length()+1);
	for (int i=0; i<val.length(); ++i)
	    os.writeByte(val.charAt(i));
	os.writeByte(0);
    }

    protected String[] read_QStringList(DataInputStream is) throws IOException
    {
	int n = is.readInt();
	String[] result = new String[n];
	for (int i=0; i<n; ++i)
	    result[i] = read_QString(is);
	return result;
    }

    protected void write_QStringList(DataOutputStream os, String[] val) throws IOException
    {
	os.writeInt(val.length);
	for (int i=0; i<val.length; ++i)
	    write_QCString(os, val[i]);
    }

    protected void write_DCOPRef(DataOutputStream os, DCOPRef ref) throws IOException
    {
	write_QCString(os, ref.app());
	write_QCString(os, ref.object());
	write_QCString(os, ref.type());
    }

    protected DCOPRef read_DCOPRef(DataInputStream is) throws IOException
    {
	return new DCOPRef(read_QCString(is), read_QCString(is), read_QCString(is));
    }

}
