[CCode(cname="GETTEXT_PACKAGE")] extern const string GETTEXT_PACKAGE;

namespace SAPG {

  const string[] authors = {
    "Gustav \"Gego/XAREN\" Hartvigsson (+GustavHartvigsson)",
  };

  int main (string[] args) {
    Intl.setlocale(LocaleCategory.MESSAGES, "");
    Intl.textdomain(GETTEXT_PACKAGE);
    Intl.bind_textdomain_codeset(GETTEXT_PACKAGE, "utf-8");
    Intl.bindtextdomain(GETTEXT_PACKAGE, "./locale");
    
    
    GLib.Environment.set_prgname (_("SAPG"));
    
    Gst.init (ref args);
    
    /* main must hold a ref to the state object. */
    AppState state = SAPG.AppState.get_app_state ();
    
    var app = new SAPG.App ();
    
    var ret_val = app.run();
    
    Gst.deinit ();
    
    return ret_val;
  }

  public
  class App : Gtk.Application {
    public App () {
      Object (application_id: "org.gego.sapg",
             flags: GLib.ApplicationFlags.FLAGS_NONE);
    }

    protected SAPG.AppWinodw window;

    protected int standard_height;

    protected int standard_width;

    protected override
    void activate () {
      this.build_ui ();
      this.add_actions ();
      this.show_all ();
    }

    void build_ui () {
      this.window = new SAPG.AppWinodw (this);
      this.window.resizable = false;
      this.window.set_size_request (0,0);
      this.window.destroy.connect (() => {
        this.quit ();
      });

      window.revealer.set_reveal_child (false);

      this.window.tgl_btn_show_volume.toggled.connect (() => {
        this.window.revealer.set_reveal_child (this.window.tgl_btn_show_volume.active);
      });

    }

    void add_actions () {
      var about_action = new GLib.SimpleAction ("about", null);
      about_action.activate.connect (() => {
        var about_dialogue = new SAPG.About (this.window);
        about_dialogue.run ();
        about_dialogue.destroy ();
      });

      var quit_action = new GLib.SimpleAction ("quit", null);
      quit_action.activate.connect (() => {
        this.window.destroy ();
        this.quit ();
      });

      this.add_action (about_action);
      this.add_action (quit_action);

      var app_menu = new GLib.Menu ();
      app_menu.append ("About", "app.about");
      app_menu.append ("Quit", "app.quit");

      this.set_app_menu (app_menu);
    }

    void show_all () {
      this.window.show_all ();
    }

    void quit_ui () {

    }
  }

  [GtkTemplate(ui = "/org/gego/sapg/window.glade")]
  public class AppWinodw : Gtk.ApplicationWindow {

    [GtkChild ]
    public Gtk.Revealer revealer;

    [GtkChild]
    public Gtk.ToggleButton tgl_btn_show_volume;
    
    [GtkChild]
    public Gtk.Button btn_play_pause;
    
    [GtkChild]
    public Gtk.Button btn_stop;
    
    [GtkChild]
    public Gtk.Button btn_rew;
    
    [GtkChild]
    public AppWinodw (Gtk.Application application) {
      Object (application: application);
      var icon_image = new Gtk.Image.from_resource ("/org/gego/sapg/icon_32.png");
      Gtk.Window.set_default_icon (icon_image.get_pixbuf ());
    }

  }

  public class About : Gtk.AboutDialog {
    public About (Gtk.Window? window) {
      this.program_name = GLib.Environment.get_prgname ();
      this.logo = (new Gtk.Image.from_resource ("/org/gego/sapg/icon_256.png")).get_pixbuf ();
      this.authors = SAPG.authors;

      this.set_modal (true);
      this.set_transient_for (window);
    }
  }
  
  /**
   * Singeltonian stucture to hold the application's state and act uppon
   * changes.
   */
  public class AppState {
    public enum State {
      STOPPED,
      PAUSED,
      PLAYING
    }
    
    private static AppState app_state = null;
    
    private AppState () {
      this.is_paused = false;
      this.is_playing = false;
    }
    
    public static AppState get_app_state () {
      if (SAPG.AppState.app_state == null) {
        SAPG.AppState.app_state = new AppState ();
      }
      return SAPG.AppState.app_state;
    }
    
    private bool is_playing;
    private bool is_paused;
    
    public AppState.State get_state () {
      if (this.is_playing) {
        return AppState.State.PLAYING;
      } else if (!this.is_playing && !this.is_paused) {
        return AppState.State.STOPPED;
      } else {
        return AppState.State.PAUSED;
      }
    }
    
    public Callback on_first_play;
    public Callback on_start_play;
    public Callback on_pause_play;
    public Callback on_stop_play; 
    public Callback on_rewind;
    
    public void play_pause_toggle () {
      if (this.is_playing) {
        /* We are playing... */
        this.is_paused = true;
        this.is_playing = false;
        this.on_pause_play ();
      } else if (!this.is_playing && !this.is_paused) {
        /* We are stopped... */
        this.is_paused = false;
        this.is_playing = true;
        this.on_first_play ();
      } else {
        /* We are paused... */
        this.is_paused = false;
        this.is_playing = true;
        this.on_start_play ();
      }
    }
    
    public void stop_play () {
      this.is_paused = false;
      this.is_playing = false;
      this.on_stop_play ();
    }
    
    public void rewind () {
      this.stop_play ();
      this.on_rewind ();
    }
    
  }
  
}
