/**
 * Oppgave19_5.java  - "Programmering i Java", 4.utgave - 2011-03-04
 * Løsningen bygger på en løsning utviklet av Simon Toresen og videreutviklet
 * av Hans Roar Sandberg for tidligere utgaver av boka.
 *
 * Denne oppgaven beskriver et grensesnitt til oppgave 5, kapittel 14.
 */
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import javax.swing.table.*;
import static javax.swing.JOptionPane.*;

import mittBibliotek.DataLeser; // se kap. 15.1 - brukes til å lese heltall

public class Oppgave19_5 {
  public static void main(String[] args) {

    /* Dørene våre har nummer 1, 2, .., 7. I prinsippet kan hvilke som helst
       dørnummer brukes. Det ligger ikke inne noe kontroll av det. */

    final int DØRNR_MAKS = 7;

    /* Ansatte og studenter har en fast mengde dører de har adgang til */
    Ansatt.fastAdgang(1);
    Ansatt.fastAdgang(2);
    Ansatt.fastAdgang(5);
    Ansatt.fastAdgang(6);

    Student.fastAdgang(2);
    Student.fastAdgang(3);


    /* Oppretter et register og fyller det med noen tilfeldige kort. */
    KortRegister register = new KortRegister();

    /* To ansattkort */
    Ansatt aKort = new Ansatt();
    aKort.tillatDør(4); // spesialtilgang, kort nr 0
    register.registrerNyttKort(aKort);
    register.registrerNyttKort(new Ansatt());  // kort nr 1

    /* To studentkort */
    Student sKort = new Student();
    sKort.tillatDør(DØRNR_MAKS); // spesialtilgang til døren med høyest nr
    register.registrerNyttKort(sKort); // kort nr 2
    register.registrerNyttKort(new Student()); // kort nr 3

    /* Ett kurskort */
    int[] kursdatoer = {20110201, 20110204, 20110208, 20110210};
    int[] kursdører = {2, 4, 5};
    Kort kKort = new Kurs(kursdører, kursdatoer, 800, 1530);
    register.registrerNyttKort(kKort);  // kort nr 4
    kKort.tillatDør(1); // ekstra dør på dette kurs-kortet

    /* Oppretter et vindu. */
    MittVindu vindu = new MittVindu("Oppgave19_5", register);
    vindu.setVisible(true);
  }
}

/**
 * Klassen MittVindu
 */
class MittVindu extends JFrame {
  private KortRegister register;

  private RegisterModell kortdata;
  private JTable kortliste;

  private JButton knappNyttKort = new JButton("Nytt Kort");
  private JButton knappEndreSperring = new JButton("Endre Sperring");
  private JButton knappDato = new JButton("Sjekk Dør og Tidspunkt");
  private JButton knappSpesialtilgang = new JButton("Spesialtilgang");


  public MittVindu(String tittel, KortRegister register) {
    super(tittel);
    this.register = register;

    kortdata = new RegisterModell(register);
    kortliste = new JTable(kortdata);

    add(new JScrollPane(kortliste), BorderLayout.NORTH);
    add(new TrykkPanel(), BorderLayout.SOUTH);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    pack();
  }

  /* Beskriver TrykkPanel */
  private class TrykkPanel extends JPanel {
    public TrykkPanel() {
      setLayout(new GridLayout(1, 2));

      knappNyttKort.setMnemonic('N');
      knappNyttKort.addActionListener(new Knappelytter());
      add(knappNyttKort);

      knappEndreSperring.setMnemonic('S');
      knappEndreSperring.addActionListener(new Knappelytter());
      add(knappEndreSperring);

      knappDato.setMnemonic('D');
      knappDato.addActionListener(new Knappelytter());
      add(knappDato);

      knappSpesialtilgang.setMnemonic('T');
      knappSpesialtilgang.addActionListener(new Knappelytter());
      add(knappSpesialtilgang);
    }
  }

  /* Lytter etter knappetrykk. */
  private class Knappelytter implements ActionListener {

    /**
     * Har laget en hjelpemetode for hver knapp. De finner du rett
     * under metoden actionPerformed().
     */
    public void actionPerformed(ActionEvent hendelse) {
      JButton knapp = (JButton) hendelse.getSource();
      if (knapp == knappNyttKort) {
        handterNyttKort();
      } else if (knapp == knappEndreSperring) {
        handterEndreSperring();
      } else if (knapp == knappDato) {
        handterSjekkTidspunkt();
      } else if (knapp == knappSpesialtilgang) {
        handterGiSpesialtilgang();
      } else {
        showMessageDialog(null, "Feil. Hit skal man ikke komme :-)");
      }

      /*
       * Nå er dataene endret. Vi må varsle fra om det,
       * slik at disse endringene kommer til syne på skjermen.
       */
      kortdata.fireTableDataChanged();
    }

    /**
     * Metoden lar brukeren velge korttype, og sørger for at kort av
     * riktig type blir laget.
     */
    private void handterNyttKort() {
      final String[] TYPER = { "Ansatt", "Student", "Kurs" };
      String type = (String) showInputDialog(null, "Velg korttype:", "Nytt Kort", INFORMATION_MESSAGE, null, TYPER, TYPER[0]);

      /* Ansatt- og student-kort er enkelt */
      if (type.equals("Ansatt")) {
        register.registrerNyttKort(new Ansatt());
      } else if (type.equals("Student")) {
        register.registrerNyttKort(new Student());
      }

      /*
       * Kurskort, leser inn dører, datoer og fra- og til klokkeslett.
       * Ingen kontroll av om datoer eller klokkeslett er gyldige.
       * Se eventuelt løsningen til oppgave 4 side 387.
       */
      else {
        int[] dører = lesDører("Hvilke dører skal dette kurskortet ha adgang til? ");
        int antall = DataLeser.lesHeltall("Hvor mange datoer? ");
        int[] datoer = new int[antall];
        for (int i = 0; i < datoer.length; i++) {
          datoer[i] = DataLeser.lesHeltall("Oppgi dato nr " + (i + 1) + " (ååååmmdd): ");
        }
        int fra = DataLeser.lesHeltall("Kurs fra kl (ttmm): ");
        int til = DataLeser.lesHeltall("Kurs til kl (ttmm): ");

        register.registrerNyttKort(new Kurs(dører, datoer, fra, til));
      }
    }

    /**
     * Metoden tar tak i de kortene brukeren har valgt. Dersom kortet er sperret,
     * åpnes det, og dersom det ikke er sperret, så sperres det.
     */
    private void handterEndreSperring() {
      int[] verdier = kortliste.getSelectedRows();
      if (verdier.length == 0) {
        showMessageDialog(null, "Ingen kort valgt.", "Feil", WARNING_MESSAGE);
      } else {
        for (int valgtKort : verdier) {
          Kort kort = (Kort) register.finnKort(valgtKort);
          if (kort != null) {
            kort.setSperret(!kort.isSperret());
          }
        }
      }
    }

    /**
     * Metoden tar inne et dørnummer, en dato og et klokkeslett.
     * Den finner ut hvilke kort som har tilgang på denne datoen.
     */
    private void handterSjekkTidspunkt() {
      int dør = DataLeser.lesHeltall("Oppgi dørnummer: ");
      int dato = DataLeser.lesHeltall("Oppgi dato (ååååmmdd): ");
      int klokkeslett = DataLeser.lesHeltall("Oppgi klokkeslett (ttmm): ");

      ArrayList<Integer> liste = register.finnTilgang(dør, dato, klokkeslett);
      if (liste.size() == 0) {
        showMessageDialog(null, "Ingen kort har tilgang til dør " +  dør + ", " +
            TidFormat.formaterDato(dato) + ", kl " +
            TidFormat.formaterKlokkeslett(klokkeslett), "Tilgang", INFORMATION_MESSAGE);
      } else {

        StringBuilder buffer = new StringBuilder();
        for (int etKort: liste) {
          buffer.append(etKort + " ");
        }

        showMessageDialog(null, "Kort med tilgang til dør " + dør + ", " +
            TidFormat.formaterDato(dato) + ", kl " + TidFormat.formaterKlokkeslett(klokkeslett) +
            ": " + buffer.toString(), "Tilgang", INFORMATION_MESSAGE);
      }
    }

    /**
     * Student- og ansatt-kort har en del dører de alltid har tilgang til. Det bestemmes
     * med klassemetoden fastAdgang(). Her er dette satt i main().
     * I tillegg kan enkelte kort få tilgang til bestemte dører. Denne metoden
     * lar brukeren angi spesialtilgang for valgte kort. Hvert valgt kort får tilgang
     * til et eget sett med dører.
     */
    private void handterGiSpesialtilgang() {
      int[] verdier = kortliste.getSelectedRows(); // henter valgte kort
      if (verdier.length == 0) {
        showMessageDialog(null, "Ingen kort valgt.", "Feil", WARNING_MESSAGE);
      } else {

        /* Hvert gjenomløp av løkkekroppen behandler et bestemt kort */
        for (int valgtKort : verdier) {
          Kort kort = (Kort) register.finnKort(valgtKort);
          if (kort != null) {
            int[] dører = lesDører("Oppgi ekstra dører for kort nr " + valgtKort);
            for (int enDør : dører) {
              kort.tillatDør(enDør);  // gir tilgang
            }
          }
        }
      }
    }

    private int[] lesDører(String ledetekst) {
      String ekstra = showInputDialog(ledetekst);

      /* Mellomrom og komma aksepteres som skilletegn mellom dørnummer */
      StringTokenizer tekst = new StringTokenizer(ekstra, ", ");
      int[] dører = new int[tekst.countTokens()];
      int dørIndeks = 0;
      try {
        while (tekst.hasMoreTokens()) {
          dører[dørIndeks] = Integer.parseInt(tekst.nextToken());
          dørIndeks++;
        }
        return dører;  // RETUR, alle dørnumer registrert
      } catch (NumberFormatException e) {
        showMessageDialog(null, "Ugyldig tall. Ingen dører registrert");
        return new int[0];
      }
    }
  }
}

/**
 * Klassen RegisterModell
 *
 */
class RegisterModell extends AbstractTableModel {
  private static final String[] KOLONNENAVN = { "KortNr", "Type", "Tilgang", "Kommentar" };
  private KortRegister register;

  public RegisterModell(KortRegister startRegister) {
    register = startRegister;
  }

  /*
   * TableModel metoder
   *
   * Dette er metoder som JTable benytter til å finne størrelse og data. Ved å
   * lage våre egne utgaver av disse kan vi lage en direkte kobling til
   * registeret.  Se kapittel 19.9.
   */

  /* Kolonnenavnene */
  public String getColumnName(int indeks) {
    return (indeks >= 0 && indeks < KOLONNENAVN.length) ? KOLONNENAVN[indeks] : "";
  }

  /* Brukeren skal ikke kunne editere i dataene */
  public boolean isCellEditable(int rad, int kolonne) {
    return false;
  }

  /* Antall kolonner. */
  public int getColumnCount() {
    return 4;
  }

  /* Antall rader er lik antall kort i registeret. */
  public int getRowCount() {
    return (register == null) ? 0 : register.finnAntKort();
  }

  /* Verdier som skal plasseres i tabellen. */
  public Object getValueAt(int rad, int kolonne) {
    switch (kolonne) {
      case 0:
        return new Integer(rad);

      case 1:
        return new String(register.finnKort(rad).finnType());

      case 2:
        return new String(register.finnKort(rad).finnTilgang());

      case 3:
        return new String(register.finnKort(rad).finnKommentar());

      default:
        return null;
    }
  }
}

/***** Her kommer problemdomeneklassene *****/

/**
 * Klassen KortRegister
 *
 * Klassen inneholder en mengde dørkort. Kortene har ikke egne identifikasjoner,
 * men identifiseres ved den plass (indeks) de har i ArrayListen 'liste'.
 * Denne indeksen blir dermed kortets nummer utad. Det går bra, fordi kort ikke
 * flyttes eller fjernes i listen.
 *
 * Klassen bruker ArrayLister til å lagre heltall (kortnummer, dørnummer).
 */

class KortRegister {
  private ArrayList<Kort> liste = new ArrayList<Kort>();

  /**
   * Metoden finner antall kort registrert.
   */
  public int finnAntKort() {
    return liste.size();
  }

  /**
   * Metoden finner et bestemt kort. Returnerer null hvis ugyldig indeks.
   */
  public Kort finnKort(int indeks) {
    return (indeks >= 0 && indeks < liste.size()) ? (Kort) liste.get(indeks) : null;
  }

  /**
   * Returnerer nummerne til de dørene som et bestemt kort har tilgang til
   * på et bestemt tidspunkt.
   */
  public String finnDører(int kortIndeks, int dato, int klokkeslett) {
    Kort kort = finnKort(kortIndeks);
    return (kort != null) ? kort.finnAlleDørerMedTilgang(dato, klokkeslett) : null;
  }

  /**
   * Returnerer en ArrayList med numrene på kortene som har tilgang
   * til en bestemt dør på et bestemt klokkeslett.
   */
  public ArrayList<Integer> finnTilgang(int dør, int dato, int klokkeslett) {
    ArrayList<Integer> tilgang = new ArrayList<Integer>();
    for (int i = 0; i < liste.size(); i++) {
      if (tilgangOk(i, dør, dato, klokkeslett)) {
        tilgang.add(i);  // auto-boxing
      }
    }
    return tilgang;
  }

  /**
   * Metoden finner ut om en bestemt person har tilgang til en bestemt
   * dør på et bestemt klokkeslett.
   * Metoden returnerer false hvis kort med oppgitt indeks ikke fins,
   * eller personen ikke har tilgang.
   */
  public boolean tilgangOk(int kortIndeks, int dør, int dato, int klokkeslett) {
    Kort kort = finnKort(kortIndeks);
    return (kort == null) ? false : kort.tilgang(dør, dato, klokkeslett);
  }

  /*   *
   * Metoden registrerer et nytt kort.
   */
  public void registrerNyttKort(Kort kort) {
    liste.add(kort);
  }

  /**
   * Metoden sperrer et kort.
   * Metoden returnerer false hvis kort med oppgitt indeks ikke fins.
   */
  public boolean sperrKort(int indeks) {
    Kort kort = finnKort(indeks);
    if (kort == null) {
      return false;
    }
    kort.setSperret(true);
    return true;
  }

  /**
   * Metoden opphever sperringen på et kort.
   * Metoden returnerer false hvis kort med oppgitt indeks ikke fins.
   */
  public boolean åpneKort(int indeks) {
    Kort kort = finnKort(indeks);
    if (kort == null) {
      return false;
    }
    kort.setSperret(false);
    return true;
  }
}

/***** Her kommer klassen Kort med subklasser *****/

/* Disse klassene lagrer heltall (dørnummer) som ArrayLister av Integer-objekter */

/**
 * Klassen Kort
 *
 */
abstract class Kort {
  public static final String SPERRET_BESKJED = "Kortet er sperret";
  public static final String ALLE_BESKJED = "Alle dører";
  public static final String INGEN_BESKJED = "Ingen dører";
  public static final int DAG_START = 700;  // kl 07:00
  public static final int DAG_SLUTT = 2300; // kl 23:00

  private boolean sperret = false;

  /**
   * For hvert kort lagrer vi de dørene som kortet åpnes spesielt for.
   * I tillegg kommer en fast mengde dører for ansatte og for studenter.
   * Disse lagres i klassevariabler, se klassene Ansatt og Student.
   */
  private ArrayList<Integer> dører = new ArrayList<Integer>();

  abstract public String finnType(); // **** NY i oppgave 19-5 ****
  abstract public String finnKommentar(); // **** NY i oppgave 19-5 ****


  /**
   * Metoden reurnerer true dersom dette kortet er sperret.
   */
  public boolean isSperret() {
    return sperret;
  }

  /**
   * Metoden brukes til å sette eller åpne sperring.
   */
  public void setSperret(boolean nySperret) {
    sperret = nySperret;
  }

  /**
   * Denne metoden brukes for å gi dette kortet tilgang til en bestemt dør
   * (i tillegg til eventuelle faste dører).
   */
  public void tillatDør(int dør) {
    dører.add(dør); // auto-boxing
  }

  /**
   * Metoden finner alle dører som dette kortet gir tilgang til på
   * et bestemt tidspunkt. Returnerer en streng for å fange alle tilfeller.
   */
  abstract public String finnAlleDørerMedTilgang(int dato, int klokkeslett);

  /**
   * Skal finne ut om kortet har tilgang til en bestemt dør på et bestemt tidspunkt.
   * Spesielle regler gjelder for alle grupper kort.
   */
  abstract public boolean tilgang(int dør, int dato, int klokkeslett);

  /**
   * Metoden returnerer en ArrayList med alle dører som dette kortet har tilgang til.
   * Her kommer ikke faste dører med. Metoden implementeres derfor også i subklassene
   * Ansatt og Student, for å få med faste dører.
   */
  protected ArrayList<Integer> finnDører() {
    return dører;
  }

  /**
   * Denne metoden lager en streng med de dørene som kortet har tilgang til.
   * Tar ikke hensyn til faste dører. Metoden implementeres derfor også i subklassene
   * Ansatt og Student, for å få med dette.
   */
  protected String finnTilgang() {
    if (sperret) {
      return SPERRET_BESKJED;
    }
    StringBuilder buf = new StringBuilder();
    for (int enDør : dører) {
      buf.append(enDør + " ");
    }
    return buf.toString();
  }
}

/**
 * Klassen Fast
 * Denne klassen tjener kun klassifiseringsformål slik vi har laget den her.
 * Kunne eventuelt lagt konstantene DAG_START og DAG_SLUTT her.
 */
abstract class Fast extends Kort {
}

/**
 * Klassen Kurs
 *
 * Det finnes ikke en mengde faste dører som alle kursdeltakere har adgang til.
 * Både dører og datoer for tilgang kodes for hvert enkelt kurskort.
 * Samme tidsperiode (klokkeslett fra - til) gjelder for alle datoene på samme kort.
 */
final class Kurs extends Kort {
  private final int[] datoer;
  private final int fraKlokka;
  private final int tilKlokka;

  public Kurs(int[] startDører, int[] startDatoer, int startFraKlokka, int startTilKlokka) {
    datoer = startDatoer;
    fraKlokka = startFraKlokka;
    tilKlokka = startTilKlokka;
    for (int enDør : startDører) {
      tillatDør(enDør);
    }
  }

  public String finnType() {  // **** NY i oppgave 19-5 ****
    return "Kurs";
  }

  public String finnKommentar() {  // **** NY i oppgave 19-5 ****
    StringBuilder buf = new StringBuilder();
    buf.append("Datoer: ");
    for (int enDato : datoer) {
      buf.append(TidFormat.formaterDato(enDato) + ", ");
    }
    buf.append(" tidsperiode, fra kl " + TidFormat.formaterKlokkeslett(fraKlokka) +
               " til kl " + TidFormat.formaterKlokkeslett(tilKlokka));
    return buf.toString();
  }

  public String finnAlleDørerMedTilgang(int dato, int klokkeslett) {
    if (isSperret()) {
      return SPERRET_BESKJED;
    }
    if (!tilgangTid(dato, klokkeslett)) {
      return INGEN_BESKJED;
    }
    return finnTilgang();
  }

  public boolean tilgang(int dør, int dato, int klokkeslett) {
    if (isSperret()) {
      return false;
    }
    if (!tilgangTid(dato, klokkeslett)) {
      return false;
    }

    /* Sjekker dørene */
    ArrayList<Integer> dører = finnDører();
    if (dører.indexOf(dør) >= 0) {
      return true;  // søker etter heltall i ArrayListen
    }
    return false;
  }

  /* Privat hjelpemetode */
  private boolean tilgangTid(int dato, int klokkeslett) {
    /* Sjekker datoen */
    boolean datoFunnet = false;
    int datoIndeks = 0;
    while (!datoFunnet && datoIndeks < datoer.length) {
      if (dato == datoer[datoIndeks]) {
        datoFunnet = true;
      } else {
        datoIndeks++;
      }
    }

    /* Deretter må klokkeslettet ligge innenfor lovlig intervall for dette kurskortet */
    if (datoFunnet && fraKlokka <= klokkeslett && klokkeslett <= tilKlokka) {
      return true;
    } else {
      return false;
    }
  }
}

/**
 * Klassen Ansatt
 *
 * Ansatte har tilgang til alle dører på dagtid.
 * Ansatte har tilgang til et begrenset utvalg dører om natta, dog med kode.
 * Det begrensede utvalget dører består av en mengde faste dører (som er klassevariabel
 * i denne klassen), og en mengde spesielle dører, som bestemmes individuelt for
 * hvert kort.
 */
final class Ansatt extends Fast {
  private static ArrayList<Integer> fasteDører = new ArrayList<Integer>();

  public static void fastAdgang(int dør) {
    fasteDører.add(dør);
  }

  public String finnType() {  // **** NY i oppgave 19-5 ****
    return "Ansatt";
  }

  public String finnKommentar() {  // **** NY i oppgave 19-5 ****
    return "Kode kreves mellom kl " + TidFormat.formaterKlokkeslett(DAG_SLUTT) + " - " +
                   TidFormat.formaterKlokkeslett(DAG_START);
  }

  public String finnTilgang() {
    String tmp = super.finnTilgang();
    if (isSperret()) {
      return tmp;
    }
    return oversiktFasteDører() + tmp;
  }

  public String finnAlleDørerMedTilgang(int dato, int klokkeslett) {
    if (isSperret()) {
      return SPERRET_BESKJED;
    }
    if (klokkeslett >= DAG_START && klokkeslett <= DAG_SLUTT) {
      return ALLE_BESKJED;
    }
    return finnTilgang();
  }

  public boolean tilgang(int dør, int dato, int klokkeslett) {
    if (isSperret()) {
      return false;
    }
    if (klokkeslett >= DAG_START && klokkeslett <= DAG_SLUTT) {
      return true;
    }

    /*
     * På natta har ansatte tilgang til faste dører og dører med
     * spesialtillatelse.
     */
    ArrayList<Integer> dørerSpesial = finnDører();
    /* Sjekker om dørnr er i en av de to ArrayListene */
    return(dørerSpesial.indexOf(dør) >= 0 || fasteDører.indexOf(dør) >= 0) ? true : false;
  }

  private static String oversiktFasteDører() {
    StringBuilder oversikt = new StringBuilder();
    for (int enDør : fasteDører) {
      oversikt.append(enDør + " ");
    }
    return oversikt.toString();
  }
}

/**
 * Klassen Student
 * Studenter har ikke tilgang til noen dører om natta.
 * De har tilgang til et begrenset utvalg dører på dagtid.
 * Det begrensede utvalget dører består av en mengde faste dører (som er klassevariabel
 * i denne klassen), og en mengde spesielle dører, som bestemmes individuelt for
 * hvert kort.
 *
 */
final class Student extends Fast {
  private static ArrayList<Integer> fasteDører = new ArrayList<Integer>();

  public static void fastAdgang(int dør) {
    fasteDører.add(dør);
  }

  public String finnType() {  // **** NY i oppgave 19-5 ****
    return "Student";
  }

  public String finnKommentar() {  // **** NY i oppgave 19-5 ****
    return "kl " + TidFormat.formaterKlokkeslett(DAG_START) + " - " +
                   TidFormat.formaterKlokkeslett(DAG_SLUTT);
  }

  public String finnTilgang() {
    String tmp = super.finnTilgang();
    return (isSperret())? tmp : oversiktFasteDører() + tmp;
  }

  public String finnAlleDørerMedTilgang(int dato, int klokkeslett) {
    if (isSperret()) {
      return SPERRET_BESKJED;
    }
    if (klokkeslett <= DAG_START || klokkeslett >= DAG_SLUTT) {
      return INGEN_BESKJED;
    }
    return finnTilgang();
  }

  public boolean tilgang(int dør, int dato, int klokkeslett) {
    if (isSperret()) {
      return false;
    }
    if (klokkeslett <= DAG_START || klokkeslett >= DAG_SLUTT) {
      return false;
    }

    /* Sjekker døra */
    ArrayList dørerSpesial = finnDører();
    /* Sjekker om dørnr er i en av de to ArrayListene */
    return (dørerSpesial.indexOf(dør) >= 0 || fasteDører.indexOf(dør) >= 0) ? true : false;
  }

  private static String oversiktFasteDører() {
    StringBuilder oversikt = new StringBuilder();
    for (int enDør : fasteDører) {
      oversikt.append(enDør + " ");
    }
    return oversikt.toString();
  }
}

/* Ny i oppgave 19-5, for å skrive ut tidspunkt på en leselig måte */
class TidFormat {
  public static String formaterDato(int dato) { // ååååmmdd
    int år = dato / 10000;
    int mndDag = dato % 10000;
    int mnd = mndDag / 100;
    int dag = mndDag % 100;

    String tid = "";
    if (dag < 10) {
      tid += "0";
    }
    tid += dag + "-";
    if (mnd < 10) {
      tid += "0";
    }
    tid += mnd + "-" + år;
    return tid;
  }

  public static String formaterKlokkeslett(int klokkeslett) { // ttmm
    int time = klokkeslett / 100;
    int min = klokkeslett % 100;

    String tid = "";
    if (time < 10) {
      tid += "0";
    }
    tid += time + ":";
    if (min < 10) {
      tid += "0";
    }
    tid += min;
    return tid;
  }
}