import java.io.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
import java.math.BigDecimal;
import static javax.swing.JFileChooser.*;
import static javax.swing.JOptionPane.*;

public class NegozioFrame extends JFrame implements Observer {

  private Negozio ilNegozio = new Negozio();
  private File negozioFile = null;
  private DefaultListModel listModelArticoli = new DefaultListModel();
  private JList listaArticoli = new JList(listModelArticoli);
  private Carrello carrello = new Carrello();
  private CarrelloFrame carrelloFrame = new CarrelloFrame(carrello);

  public NegozioFrame() {
    super("Nuovo negozio - Gestione Negozio");
    JMenuBar menuBar = new JMenuBar();
    setJMenuBar(menuBar);
    menuBar.add(creaFileMenu());
    menuBar.add(creaActionMenu());
    add(listaArticoli);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setBounds(300,300,400,400);
    setVisible(true);
    ilNegozio.addObserver(this);
  }

  private JMenu creaFileMenu() {
    JMenu menu = new JMenu("File");
    menu.add(creaItem("Nuovo negozio", nuovoListener));
    menu.add(creaItem("Apri negozio esistente", apriNegozioListener));
    menu.add(creaItem("Salva negozio", salvaNegozioListener));
    menu.add(creaItem("Salva negozio con nome", salvaNegozioConNomeListener));
    return menu;
  }

  private JMenu creaActionMenu() {
    JMenu menu = new JMenu("Azioni");
    menu.add(creaItem("Aggiungi articolo in vendita", aggiungiArticoloListener));
    menu.add(creaItem("Togli articolo in vendita", togliArticoloListener));
    menu.add(creaItem("Visualizza il carrello", visualizzaCarrelloListener));
    menu.add(creaItem("Aggiungi al carrello", aggiungiAlCarrelloListener));
    return menu;
  }

  public JMenuItem creaItem(String nomeItem, ActionListener listener) {
    JMenuItem item = new JMenuItem(nomeItem);
    item.addActionListener(listener);
    return item;
  }

  private ActionListener nuovoListener =
    new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        ilNegozio = new Negozio();
        listModelArticoli.removeAllElements();
        carrello = new Carrello();
        carrelloFrame = new CarrelloFrame(carrello);
      }
    };

  private ActionListener apriNegozioListener =
    new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        apriNegozio();
      }
    };

  private ActionListener salvaNegozioListener =
    new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        salvaNegozio();
      }
    };

  private ActionListener salvaNegozioConNomeListener =
    new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        salvaNegozioConNome();
      }
    };


  private ActionListener aggiungiArticoloListener =
    new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        Articolo art = readArticolo();
        if(art != null) {
          ilNegozio.aggiungiArticolo(art);
          setListaArticoli();
        }
      }
    };

  private ActionListener togliArticoloListener =
    new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        int i = listaArticoli.getSelectedIndex();
        if(i != -1) ilNegozio.eliminaArticolo(i);
        setListaArticoli();
      }
    };

  private ActionListener visualizzaCarrelloListener =
    new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        carrelloFrame.setVisible(true);
      }
    };

  private ActionListener aggiungiAlCarrelloListener =
    new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        int i = listaArticoli.getSelectedIndex();
        if(i != -1) carrello.aggiungiArticolo(ilNegozio.articolo(i));
        carrelloFrame.setVisible(true);
      }
    };


  private void salvaNegozio() {
    if(negozioFile == null) salvaNegozioConNome();
    else {
      try {
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(negozioFile));
        out.writeObject(ilNegozio);
      }
      catch(IOException ex) {
        showErrorMessage("Errore: non posso salvare il negozio");
      }
    }
  }

  private void salvaNegozioConNome() {
    JFileChooser fileChooser = new JFileChooser(directoryCorrente());
    fileChooser.setFileFilter(new FiltroNegozi());
    int option = fileChooser.showSaveDialog(this);
    if(option == APPROVE_OPTION) {
      try {
        negozioFile = fileChooser.getSelectedFile();
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(negozioFile));
        out.writeObject(ilNegozio);
        setTitle(negozioFile.getName() + " - Gestione Negozio");
      }
      catch(IOException ex) {
        showErrorMessage("Errore: non posso salvare il negozio");
      }
    }
  }

  private void apriNegozio() {
    JFileChooser fileChooser = new JFileChooser(directoryCorrente());
    fileChooser.setFileSelectionMode(FILES_AND_DIRECTORIES);
    fileChooser.setFileFilter(new FiltroNegozi());
    int option = fileChooser.showOpenDialog(this);
    if(option == APPROVE_OPTION) {
      negozioFile = fileChooser.getSelectedFile();
      try {
        ObjectInputStream in = new ObjectInputStream(new FileInputStream(negozioFile));
        ilNegozio = (Negozio) in.readObject();
        setListaArticoli();
        setTitle(negozioFile.getName() + " - Gestione Negozio");
      }
      catch(Exception ex) {showErrorMessage("Errore: non posso aprire il negozio");}
    }
  }

  private void showErrorMessage(String s) {
    showMessageDialog(this, s);
  }

  private File directoryCorrente() {
    File f;
    try {
      f = new File(new File(".").getCanonicalPath());
    } catch (IOException e) {
      showErrorMessage("Errore: non posso accedere alla cartella corrente");
      return null;
    }
    return f;
  }

  private class FiltroNegozi extends javax.swing.filechooser.FileFilter {
    public boolean accept(File file) {
      if (file.isDirectory()) return true;
      else
        return file.getName().endsWith(".ngz");
    }

    public String getDescription() {
      return "*.ngz";
    }
  }

  BigDecimal leggiPrezzo() {
    Scanner scan;
    do {
      String prezzoString = showInputDialog(this, "Prezzo in euro (intero o con virgola):");
      if(prezzoString == null) return null;
      scan = new Scanner(prezzoString);
    } while(!scan.hasNextDouble());
    String prezzoItaliano = scan.next();
    return new BigDecimal(prezzoItaliano.replace(".", "").replace(',', '.'));
  }

  private Articolo readArticolo() {
    String nome = showInputDialog(this, "Nome dell'articolo:");
    if(nome == null) return null;
    BigDecimal prezzo = leggiPrezzo();
    if(prezzo == null) return null;
    return new Articolo(nome, prezzo);
  }

  void setListaArticoli() {
    listModelArticoli.removeAllElements();
    for(int i = 0; i < ilNegozio.numArticoli(); i++) {
      listModelArticoli.addElement(ilNegozio.articolo(i).toString());
    }
  }

  int readPositiveInt(String prompt) {
    Scanner input;
    int n;
    do {
      String inputString = showInputDialog(this, prompt);
      if(inputString == null) return -1;
      else input = new Scanner(inputString);
    } while(!input.hasNextInt() || (n = input.nextInt()) <= 0);
    return n;
  }

  public void update(Observable o, Object arg) {
    if(arg instanceof String)
      listModelArticoli.addElement((String)arg);
    else {
      Integer i = (Integer)arg;
      listModelArticoli.removeElementAt(i);
    }
  }

}



