/******************************************************************************
 ** $Id: Anmeldung.java 1680 2019-01-20 21:15:21Z wmh $
 ** Diese Datei ist Bestandteil der Java-Quelltexte des Würfelspiels JaFuffy.
 ******************************************************************************
 ** Copyright (C) Wolfgang Hauck <wolfgang.hauck@3kelvin.de>
 ******************************************************************************
 ** This program is free software: you can redistribute it and/or modify
 ** it under the terms of the GNU General Public License as published by
 ** the Free Software Foundation, either version 3 of the License, or
 ** (at your option) any later version.
 **
 ** This program is distributed in the hope that it will be useful,
 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ** GNU General Public License for more details.
 **
 ** You should have received a copy of the GNU General Public License
 ** along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************
 ** Die aktuellste Version von JaFuffy findet sich im Internet unter
 ** <http://jafuffy.3kelvin.de>.
 **
 ** Kommentare, Fehler oder Erweiterungswünsche bitte per E-Mail senden an
 ** <jafuffy@3kelvin.de>.
 ******************************************************************************/
package jafuffy.organisation;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

/** Führt die Anmeldung für die Durchführung eines Turniers über ein lokales Netzwerk durch. */
class Anmeldung extends Timer {

    /** Wiederholung des Anmeldevorgangs. */
    private class Wiederholung extends TimerTask {
        @Override
        public void run() {
            try {
                serialisiere(new Nachricht(absender, teilnehmer, null));
            } catch (SocketException exception) {
                cancel();
            } catch (IOException exception) {
                exception.printStackTrace();
            }
        }
    }

    /** Anmeldevorgang wird alle 1000ms wiederverholt. */
    private static final int PERIODE = 1000;

    /** Absenderadresse dieser Austragungsstätte für das Turnier. */
    private final Kontakt absender;
    /** Teilnehmer diese Austragungsstätte für das Turnier. */
    private final ArrayList<String> teilnehmer;
    /** Socket für die Organisation eines Turniers über ein lokales Netzwerk. */
    private final MulticastSocket socket;

    /**
     * Erzeugt die Anmeldung zur Durchführung der Anmeldevorgänge.
     * 
     * @param absender
     *            Die Absenderadresse dieser Austragungsstätte.
     * @param teilnehmer
     *            Die Teilnehmer dieser Austragungsstätte.
     * @param socket
     *            Socket für die Organisation des Turnierbetriebs.
     */
    Anmeldung(Kontakt absender, ArrayList<String> teilnehmer, MulticastSocket socket) {
        this.absender = absender;
        this.teilnehmer = teilnehmer;
        this.socket = socket;
    }

    /** Serialisiert und verschickt ein Objekt über den Organisationssocket. */
    private void serialisiere(Object object) throws IOException, SocketException {
        ByteArrayOutputStream bytestrom = new ByteArrayOutputStream();
        ObjectOutputStream objektstrom = new ObjectOutputStream(new BufferedOutputStream(bytestrom));
        objektstrom.writeObject(object);
        objektstrom.close();
        byte[] bytes = bytestrom.toByteArray();
        bytestrom.close();
        DatagramPacket paket = new DatagramPacket(bytes, bytes.length, InetAddress.getByName(Leitung.ADRESSE),
                Leitung.PORT);
        socket.send(paket);
    }

    /** Versendet eine Nachricht. */
    void sende(Nachricht nachricht) {
        try {
            serialisiere(nachricht);
        } catch (IOException exception) {
            exception.printStackTrace();
        }
    }

    /** Startet die periodische Durchführung der Anmeldevorgänge. */
    void starte() {
        scheduleAtFixedRate(new Wiederholung(), 0, PERIODE);
    }

}
