/** FILE: simulator.java **/


package SIMULA;

import BUFFER.*;
import java.io.*;
import java.util.*;

// Referenced classes of package SIMULA:
//            Maingetter, fine, getter, grafico, 
//            putter

/*
 * CLASS simulator
 *
 * Al momento della creazione, presi in input gli opportuni parametri (--> vedi interfaccia.java),
 * salva il contenuto del file in un array di byte, lo converte in stringa per poi tokenuzzarlo
 * (spezzettarlo in singoli messaggi) con tre delimitatori, lo spazio la tabulazione e l'invio.
 * Quando viene lanciato crea un thread maingetter (--> vedi Maingetter.java) e N thread putter
 * dove N=numero di token in input(messaggi).
 * Poi attende che siano terminati tutti i getter(--> vedi getter.java) lanciati da maingetter. 
 * Infine lancia due oggetti grafico (--> vedi grafico.java) e uno fine (--> vedi fine.java).
 *
 */

public class simulator extends Thread
{

    /*
     * COSTRUTTORE(1)
     *
     * impostazione delle variabili e dei token dal file
     * inoltre mi ricavo modulo moltipliando beta per in numero di messaggi
     *
     */

    simulator(FileInputStream fileinputstream, int i, float f, String s, boolean flag)
    {
        System.out.println("\n\nNuova Simulazione");
        totcaratteri = 0;
        piugrande = 0;
        piupiccola = 200;
        numparole = 0;
        tolleranza = 0;
        nograp = flag;
        nomefile = s;
        alpha = f;
        beta = i;
        try
        {
            byte abyte0[] = new byte[fileinputstream.available()];  // crea un vettore di appoggio
            fileinputstream.read(abyte0);  // vi copia dentro il contenuto del file
            fileinputstream.close();  // chiude il file
            String s1 = new String(abyte0, 0); // copia il contenuto del vettore in una nuova stringa
            tin = new StringTokenizer(s1); // tokenizza la stringa
        }
        catch(Exception _ex) { }
        modulo = i * tin.countTokens();  // beta*numero_messaggi per ottenere un tempo medio di interarrivo
                                         // pari a beta impostiamo il limite superiore di dormita(modulo).
                                         // ipotizzando una distribbuzione casuale ma omoggenea possiamo 
                                         // affermare che il tempo medio di interarrivo č proprio beta.
    }


    /*
     * COSTRUTTORE(2)
     *
     * impostare, secondo i dati in input, la politica di gestione del buffer.
     * (--> vedi package BUFFER - buffer.java)
     */

    public simulator(boolean flag, float f, int i, FileInputStream fileinputstream, String s, boolean flag1)
        throws IOException
    {
        this(fileinputstream, i, f, s, flag1);
        if(flag)
        {
            politica = "F.I.F.O.";
            buffer = new bufferfi();  // FIFO --> vedi bufferfi.java
            return;
        }
        else
        {
            politica = "Anarchica";
            buffer = new bufferan();  // ANARCHICA --> vedi bufferan.java
            return;
        }
    }


    /*
     * COSTRUTTORE(3)
     *
     * impostare, secondo i dati in input, la politica di gestione del buffer.
     * (--> vedi package BUFFER - buffer.java)
     */

    public simulator(int i, float f, int j, FileInputStream fileinputstream, String s, boolean flag)
        throws IOException
    {
        this(fileinputstream, j, f, s, flag);
        politica = "Personalizzata";
        buffer = new buffermy(i);   // PERSONALIZZATA --> vedi buffermy.java
        tolleranza = i;
    }


    /*
     * METODO caso()
     *
     * restituisce un valore casuale da 0 a modulo (cosč modulo??  --> vedi COSTRUTTORE(1))
     */

    static float caso()
    {
        return (float)Math.abs(1.0D + (double)((float)r.nextInt() % (float)modulo));
    }


    /*
     * METODO caricaparola()
     *
     * restituisce un messaggio (token) effettuando alcuni controlli:
     *    1) piupiccola e piugrande per avere il range dei messaggi inviati
     *    2) se il messaggio č pių lungo di 200 caratteri restituisce 200 asterischi
     *
     */

    private String caricaparola()
    {
        String s = "";
        try
        {
            s = tin.nextToken();
        }
        catch(Exception _ex) { }
        if(s == " ")
            s = "*";
        if(s.length() > 200)
            for (int h=0; h<200; h++)
                s = s+ '*';
        totcaratteri += s.length();
        if(piupiccola > s.length())
            piupiccola = s.length();
        if(piugrande < s.length())
            piugrande = s.length();
        numparole++;
        return s;
    }



    /*
     * METODO visualizza_accessi()
     *
     * crea tre finestre: due grafico (--> vedi grafico.java) e una fine (--> vedi fine.java)
     * 
     */

    public void visualizza_accessi()
    {
        if(buffer.accessi != 0)
        {
            grafico grafico1 = new grafico(buffer.Startaccput, "Mittenti");
            grafico grafico2 = new grafico(buffer.Startaccget, "Destinatari");
            new fine(grafico1.tempomedio, grafico2.tempomedio);
        }
    }


    /*
     * METODO run()
     *
     * crea un thread maingetter (--> vedi Maingetter.java) e N thread putter dove N=numero di token
     * in input(messaggi).
     * Poi attende che siano terminati tutti i getter(--> vedi getter.java) lanciati da maingetter. 
     */

    public void run()
    {
        int i = tin.countTokens();
        T = new getter[i];
        Maingetter maingetter = new Maingetter(buffer);
        maingetter.start();
        millisecondi = (new Date()).getTime();  // prende i millisecondi di partenza
        try
        {
            for(int j = 0; j < i; j++)
                (new putter(buffer, caricaparola())).start(); // crea e lancia il thread

            maingetter.join();  // attende che maingetter termini
            for(int k = 0; k < i; k++)
                T[k].join();  // attende che termini il thread

        }
        catch(Exception _ex) { }
        millisecondi = (new Date()).getTime() - millisecondi;  // tempo che impiega la simulazione
        visualizza_accessi();
    }


    /*
     * VARIABILI
     *
     */

    buffer buffer;
    static long millisecondi;
    static float alpha;
    static String nomefile;
    static Random r = new Random();
    static int beta;
    static getter T[];
    static String politica;
    static int totcaratteri;
    static int piugrande;
    static int piupiccola = 200;
    static int numparole;
    static int tolleranza;
    static int maxget;
    static int maxput;
    StringTokenizer tin;
    static int modulo;
    static int chiudi;
    static boolean nograp;

}