/**
 */

import Six.Sixp.Client.*;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Vector;


public class Demo implements IClientLogging
{

    private Client _client;
    private ISession _sess;
    private Boolean _asynchronous;
    private RequestHandler _requestHandler;
    private RequestEventListener _requestEventListener;

    public Demo()
    {
        _requestHandler=new RequestHandler();
        _requestEventListener=new RequestEventListener(_requestHandler);
        RequestItem ri;
        ri=new RequestItem("/rt/stock/trade", AcceptFormat.Table, true,_requestEventListener);
        _requestHandler.AddRequestItem(ri);
        ri=new RequestItem("/rt/stock/", AcceptFormat.Table, true,_requestEventListener);
        _requestHandler.AddRequestItem(ri);
        ri=new RequestItem("/rt/stock/?~period=\"close\"", AcceptFormat.Table, true,_requestEventListener);
        _requestHandler.AddRequestItem(ri);
        ri=new RequestItem("/rt/index/all", AcceptFormat.Table, true,_requestEventListener);
        _requestHandler.AddRequestItem(ri);
    }

    public void run()
    {

        _client=new Client();
        _client.SetLogging(this);
        SixpServerSettings setting=null;
        try {
            setting = new SixpServerSettings("services.test.six-telekurs.se", 50001);
        }
        catch (SixpExceptionInvalidParameter e)
        {
            System.out.println("Exception at SixpServerSettings " + e.getMessage());
            return;
        }
        Vector<SixpServerSettings> settings = new Vector<SixpServerSettings>();
        settings.add(setting);


        //Toggle _asynchronous to change between sync. or async.
        // Don't do like this in your code. Choose one of sync. or async.
        // This demo does it like this to be able to demonstrate both in one source.
        _asynchronous=false;

        //Toggle between ReconnectResubscribe and ReconnectNoResubscribe to get resubscribing
        // by the api or not. Again choose one approach in your code..
        ReconnectStrategy rs=ReconnectStrategy.ReconnectResubscribe;

        //Change to your credentials
        ClassicLogin cl=new ClassicLogin("username","password");

        SessionEventListener session_event_listener = new SessionEventListener(_asynchronous,_requestHandler,rs,cl);
        try
        {
            _sess=_client.CreateSession(settings,rs,5,null,session_event_listener);
            _requestEventListener.SetSession(_sess);
        }
        catch (Exception e)
        {
            System.out.println("Exception at CreateSession " + e.getMessage());
        }

        //Create a ClassicLogin

        if (_asynchronous)
        {
            //Use asynchronous connection and login
            //The call to ConnectAsync will return immediately.
            //Use OnError or OnConnected in ISessionEventListener to determine Ok or error.
            //If OnConnected gets call this means success and you may continue and call
            //LoginAsync (in OnConnected callback) if it complies with your reconnect strategy.
            //See the SessionEventListener.OnConnected method in this demo.
            try
            {
                _sess.ConnectAsync();
            }
            catch (Exception e)
            {
                System.out.println(e.getMessage());
            }
        }
        else
        {
            //Use synchronous connection and login
            //This means that both Connect and Login will block until finished.
            //The IRequest is always asynchronous which means that the call on Execute will
            //return immediately.  Use the callback functions in IRequestEventListener to determine whether
            //the call to Execute was Ok or not (OnError,OnInitTable,OnText)
            try
            {
                _sess.Connect();
                _sess.Login(cl);
                if (_requestHandler.IsOkToExecuteAllAtOnce())
                {
                    //Execute all at once since num<30. See IsOkToExecuteAllAtOnce method for changing this value
                    RequestItem ri;
                    do {
                        ri=_requestHandler.PopRequestItem();
                        if (ri!=null)
                        {
                            IRequest r=_sess.CreateRequest(ri.getPrl(),ri.getFormat(),ri.getSubscribe(),ri.getEventListener());
                            _requestHandler.SetRequestOnRequestItem(ri,r);
                            r.ExecuteAsync();
                        }
                    } while (ri!=null);
                }
                else
                {
                    //execute one by one.
                    RequestItem ri=_requestHandler.PopRequestItem();
                    if (ri!=null)
                    {
                        IRequest r=_sess.CreateRequest(ri.getPrl(),ri.getFormat(),ri.getSubscribe(),ri.getEventListener());
                        _requestHandler.SetRequestOnRequestItem(ri,r);
                        r.ExecuteAsync();
                    }
                }

            }
            catch (Exception e)
            {
                System.out.println(e.getMessage());
            }
        }

        try
        {
            System.in.read();
        }
        catch (Exception e)
        {

        }

    }


    public static void main(String[] args)
    {
        new Demo().run();
    }


    public static String GetDateTimeString()
    {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date today = Calendar.getInstance().getTime();
        return df.format(today);
    }


//****************************************************************************
//* This sample implements the logging interface in the main class
//* just to keep the amount of code to a minimum.
//****************************************************************************
    public void OnLogMessage(LogLevel logLevel, String s)
    {
        //This callback is called when the API want to log something
        System.out.println(GetDateTimeString() + ": " + s);
    }

    public void OnLogMessage(LogLevel logLevel, String s, Exception e)
    {
        //This callback is called when the API want to log something
        System.out.println(GetDateTimeString() + ": Exception occured " + e.getMessage() +" " + s);
    }

    public boolean getIsDebugLoggingEnabled()
    {
        //This method is called each time the API want to log some debug info.
        //Return true to allow it.
        return true;
    }
}
