/*
 *  Copyright (C) 2008 Kristian Kristola
 *
 *  This program is distributed under the terms of the
 *  GNU General Public License.
 *
 *  This file is part of Dave the Ordinary Spaceman.
 *
 *  Dave the Ordinary Spaceman 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.
 *
 *  Dave the Ordinary Spaceman 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 Dave the Ordinary Spaceman. If not, see
 *  <http://www.gnu.org/licenses/>.
 *
 */

#ifndef _RUOTSIN_EDUSTALLA_MERKILLINEN_ONOMATOPOEETTINEN_TARINA_ESITETTY_
#define _RUOTSIN_EDUSTALLA_MERKILLINEN_ONOMATOPOEETTINEN_TARINA_ESITETTY_

#include <vector>
#include <list>
#include "model.h"
#include "analog_effects.h"

using namespace std;

class Remote : public Model, private Effect
{
public:
  Remote();
  ~Remote();

  void render_remote();
  void render_screen_to_texture();

  enum Function
  {
    NOTHING,
    POWER,
    GO_TO_TELETEXT, EXIT_TELETEXT,

    N0,
    N1, N2, N3,
    N4, N5, N6,
    N7, N8, N9,

    REWIND,
    PAUSE,
    FAST_FORWARD,
    STOP,
    PLAY,
    RECORD,

    VOLUME_UP, VOLUME_DOWN,
    CHANNEL_UP, CHANNEL_DOWN,
    MUTE
  };

  void press(Function button);
  void release();
  void cycle(float dt, float time);
  Function get_pressed() const {return pressed;}
  bool vcr_empty() const;
  void clear_record();
  bool is_paused() const {return paused;}

private:
  int button_count;
  Scene *scene;
  Model *buttons;
  Model *screen;
  Model *gaps;
  Function pressed;
  float changed_at;
  float state;
  bool paused;
  GLFramebuffer screen_fbo;
  GLColorTexture2D screen_texture;
  Image grid;
  Teletext hud_score;
  Teletext hud_voltage;
  Teletext hud_parts;
  Teletext hud_cass;
  Teletext hud_active_ability;

  float titration(float x);
};

//template <size_t buffer_size>
class Storyboard
{
public:
  enum Purpose {
    REWIND, PLAYBACK
  };

  Storyboard(Purpose m, size_t initial_entries);
  ~Storyboard();

  void record_new_frame();
  char *record_entry();

  char *pop_entry();
  void pop_frame();

  bool empty() const {return frames.empty();}
  void clear();
  void begin();
  bool at_first() {return current_frame == frames.begin();}

private:
  const Purpose purpose;
  const size_t initial_entries;

  class Frame
  {
  public:
    Frame(size_t initial_entries);
    ~Frame();

    char *record_entry();
    char *pop_entry();

  private:
    class Entry
    {
    public:
      Entry() {};
      ~Entry() {};
      operator char *()
      {
	return buffer;
      }
    private:
      char buffer[256/*buffer_size*/];
    };
    vector<Entry> entries;
    size_t position;
  };
  list<Frame> frames;
  list<Frame>::iterator current_frame;
};

#endif
