/*
 * Copyright (c) 2014, 2015 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.oomph.setup.ui.questionnaire;

import org.eclipse.oomph.preferences.PreferencesFactory;
import org.eclipse.oomph.setup.ui.questionnaire.AnimatedCanvas.Animator;

import org.eclipse.emf.common.util.URI;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Path;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Eike Stepper
 */
public class GearAnimator extends Animator
{
  public static final String RECORDER_PREFERENCE_KEY = "RECORDER_PREFERENCE_KEY";

  public static final int NONE = -1;

  public static final int PAGE_WIDTH = 620;

  public static final int PAGE_HEIGHT = 420;

  public static final int BORDER = 30;

  public static final int GEARS = 7;

  private static final int TEETH = 8;

  private static final float ANGLE = 360 / TEETH;

  private static final double RADIAN = 2 * Math.PI / 360;

  private static final int EXIT = NONE - 1;

  private static final int BACK = EXIT - 1;

  private static final int NEXT = BACK - 1;

  private static final int CHOICES = NEXT - 1;

  private static final String[] TITLES = { "Welcome to Eclipse", "Refresh Resources Automatically?", "Show Line Numbers in Editors?",
      "Check Spelling in Text Editors?", "Execute Jobs in Background?", "Encode Text Files with UTF-8?", "Enable Preference Recorder?" };

  static final int BIG_FONT_PX = 48;

  static final int NORMAL_FONT_PX = (int)(BIG_FONT_PX * .75);

  private static Color WHITE;

  private static Color GRAY;

  private static Color DARK_GRAY;

  private final List<Listener> listeners = new ArrayList<Listener>();

  private Color purple;

  private Color tooltipColor;

  private Font tooltipFont;

  private Font bigFont;

  private Font hoverFont;

  private Font normalFont;

  private Font numberFont;

  private Image exit;

  private Image exitHover;

  private Image question;

  private final Image[] welcomeImages = new Image[2];

  private final Image[] summaryImages = new Image[2];

  private final Image[] backImages = new Image[2];

  private final Image[] nextImages = new Image[2];

  private final Image[] yesImages = new Image[5];

  private final Image[] noImages = new Image[5];

  private final Page[] pages = new Page[GEARS + 1];

  private final Point[] tooltipPoints = new Point[pages.length];

  private final Path[] gearPaths = new Path[GEARS + 1];

  private final Color[] gearBackground = new Color[2];

  private final Color[] gearForeground = new Color[2];

  private float radius;

  private int pageY;

  private int answerY;

  private int buttonR;

  private long startAnimation;

  private float speed;

  private float angle;

  private boolean overflow;

  private int selection;

  private int oldSelection = NONE;

  private int hover = NONE;

  private int oldHover = NONE;

  private Image pageBuffer;

  private GC pageGC;

  private Image oldPageBuffer;

  private GC oldPageGC;

  private boolean pageBufferUpdated;

  private boolean oldShowOverlay;

  private boolean summaryShown;

  private Rectangle exitBox;

  private Rectangle backBox;

  private Rectangle nextBox;

  public GearAnimator(Display display)
  {
    super(display);
    WHITE = display.getSystemColor(SWT.COLOR_WHITE);
    GRAY = display.getSystemColor(SWT.COLOR_GRAY);
    DARK_GRAY = display.getSystemColor(SWT.COLOR_DARK_GRAY);
  }

  @Override
  protected void init()
  {
    super.init();
    Display display = getDisplay();

    bigFont = createFont(BIG_FONT_PX, PAGE_WIDTH, TITLES);
    hoverFont = createFont(BIG_FONT_PX + 6, PAGE_WIDTH, TITLES);
    normalFont = createFont(NORMAL_FONT_PX, PAGE_WIDTH, TITLES);
    numberFont = createFont(24);
    tooltipFont = createFont(16);

    exit = loadImage("exit.png");
    exitHover = loadImage("exit_hover.png");
    question = loadImage("question.png");

    welcomeImages[0] = loadImage("welcome.png");
    welcomeImages[1] = loadImage("welcome_select.png");

    summaryImages[0] = loadImage("summary.png");
    summaryImages[1] = loadImage("summary_select.png");

    backImages[0] = loadImage("back.png");
    backImages[1] = loadImage("back_hover.png");

    nextImages[0] = loadImage("next.png");
    nextImages[1] = loadImage("next_hover.png");

    buttonR = nextImages[0].getBounds().height / 2;
    answerY = PAGE_HEIGHT + 4 * BORDER - buttonR;

    yesImages[0] = loadImage("yes.png");
    yesImages[1] = loadImage("yes_select.png");
    yesImages[2] = loadImage("yes_hover.png");
    yesImages[3] = loadImage("yes_big.png");
    yesImages[4] = loadImage("yes_badge.png");

    noImages[0] = loadImage("no.png");
    noImages[1] = loadImage("no_select.png");
    noImages[2] = loadImage("no_hover.png");
    noImages[3] = loadImage("no_big.png");
    noImages[4] = loadImage("no_badge.png");

    radius = 32;
    setSize((int)(GEARS * 2 * radius), (int)(2 * radius));
    pageY = getHeight() + 2 * BORDER;

    // Not selected.
    gearBackground[0] = createColor(169, 171, 202);
    gearForeground[0] = createColor(140, 132, 171);

    // Selected.
    gearBackground[1] = createColor(247, 148, 30);
    gearForeground[1] = createColor(207, 108, 0);

    purple = createColor(43, 34, 84);
    tooltipColor = createColor(253, 232, 206);

    pages[0] = new ImagePage(0, TITLES[0], 0, 0, 0, new TextAnswer(""));
    pages[1] = new PreferencePage(1, TITLES[1], 0, 5, 29, "/instance/org.eclipse.core.resources/refresh.lightweight.enabled");
    pages[2] = new PreferencePage(2, TITLES[2], 1, 19, 30, "/instance/org.eclipse.ui.editors/lineNumberRuler");
    pages[3] = new PreferencePage(3, TITLES[3], 1, 186, 37, "/instance/org.eclipse.ui.editors/spellingEnabled");
    pages[4] = new PreferencePage(4, TITLES[4], 0, 23, 160, "/instance/org.eclipse.ui.workbench/RUN_IN_BACKGROUND");
    pages[5] = new PreferencePage(5, TITLES[5], 0, 181, 95, "/instance/org.eclipse.core.resources/encoding", "UTF-8", null);
    pages[6] = new PreferencePage(6, TITLES[6], 1, 57, 82, RECORDER_PREFERENCE_KEY);
    pages[7] = new SummaryPage(7, "Summary");

    pageBuffer = new Image(display, PAGE_WIDTH, PAGE_HEIGHT);
    pageGC = new GC(pageBuffer);
    pageGC.setAdvanced(true);

    oldPageBuffer = new Image(display, PAGE_WIDTH, PAGE_HEIGHT);
    oldPageGC = new GC(oldPageBuffer);
    oldPageGC.setAdvanced(true);
  }

  @Override
  protected void dispose()
  {
    for (Path path : gearPaths)
    {
      if (path != null)
      {
        path.dispose();
      }
    }

    for (Page page : pages)
    {
      if (page != null)
      {
        page.dispose();
      }
    }

    pageGC.dispose();
    pageBuffer.dispose();
    oldPageGC.dispose();
    oldPageBuffer.dispose();
    super.dispose();
  }

  public Font getBigFont()
  {
    return bigFont;
  }

  public Font getHoverFont()
  {
    return hoverFont;
  }

  public Font getNormalFont()
  {
    return normalFont;
  }

  public final void addListener(Listener listener)
  {
    synchronized (listeners)
    {
      listeners.add(listener);
    }
  }

  public final Listener[] getListeners()
  {
    synchronized (listeners)
    {
      return listeners.toArray(new Listener[listeners.size()]);
    }
  }

  public final void removeListener(Listener listener)
  {
    synchronized (listeners)
    {
      listeners.remove(listener);
    }
  }

  public void restart()
  {
    angle = 0;
    speed = 0;
  }

  public final Page[] getPages()
  {
    return pages;
  }

  public final int getSelection()
  {
    return selection;
  }

  public final void setSelection(int selection)
  {
    hover = NONE;
    oldHover = NONE;

    if (selection < 0)
    {
      selection = 0;
      overflow = true;
    }
    else if (selection > pages.length - 1)
    {
      selection = pages.length - 1;
      overflow = true;
    }

    if (overflow)
    {
      overflow = false;
      while (advance())
      {
        // Just advance.
      }

      overflow = true;
      return;
    }

    oldSelection = this.selection;
    this.selection = selection;
    if (getSelectedPage() instanceof SummaryPage)
    {
      summaryShown = true;
    }

    Image tmpPageBuffer = oldPageBuffer;
    oldPageBuffer = pageBuffer;
    pageBuffer = tmpPageBuffer;

    GC tmpPageGC = oldPageGC;
    oldPageGC = pageGC;
    pageGC = tmpPageGC;

    pageBufferUpdated = false;

    restart();
  }

  public final int getOldSelection()
  {
    return oldSelection;
  }

  public final Page getSelectedPage()
  {
    return pages[selection];
  }

  @Override
  protected boolean onKeyPressed(KeyEvent e)
  {
    if (e.keyCode == SWT.ESC)
    {
      exit();
      return true;
    }

    if (e.keyCode == SWT.HOME)
    {
      setSelection(0);
      return true;
    }

    if (e.keyCode == SWT.END)
    {
      setSelection(GearAnimator.GEARS);
      return true;
    }

    if (e.keyCode == SWT.ARROW_RIGHT || e.keyCode == SWT.PAGE_DOWN)
    {
      setSelection(getSelection() + 1);
      return true;
    }

    if (e.keyCode == SWT.ARROW_LEFT || e.keyCode == SWT.PAGE_UP)
    {
      setSelection(getSelection() - 1);
      return true;
    }

    if (e.character >= '0' && e.character <= '6')
    {
      setSelection(e.character - '0');
      return true;
    }

    if (e.character == 13)
    {
      Page page = getSelectedPage();
      if (page instanceof SummaryPage)
      {
        page.doAnswer(0);
      }
      else
      {
        setSelection(getSelection() + 1);
      }

      return true;
    }

    if (e.character == 'y' || e.character == 'Y' || e.character == '+')
    {
      Page page = getSelectedPage();
      if (page instanceof PreferencePage)
      {
        page.doAnswer(0);
      }

      return true;
    }

    if (e.character == 'n' || e.character == 'N' || e.character == '-')
    {
      Page page = getSelectedPage();
      if (page instanceof PreferencePage)
      {
        page.doAnswer(1);
      }

      return true;
    }

    return false;
  }

  @Override
  protected boolean onMouseMove(int x, int y)
  {
    if (x != Integer.MIN_VALUE && y != Integer.MIN_VALUE)
    {
      GC gc = new GC(getCanvas());
      for (int i = 0; i < gearPaths.length; i++)
      {
        Path path = gearPaths[i];
        if (path != null && path.contains(x, y, gc, false))
        {
          if (i != hover)
          {
            hover = i;
          }

          return true;
        }
      }

      if (exitBox != null && exitBox.contains(x, y))
      {
        hover = EXIT;
        return true;
      }

      Page page = getSelectedPage();
      if (page != null)
      {
        if (page.showBack() && backBox != null && backBox.contains(x, y))
        {
          hover = BACK;
          return true;
        }

        if (page.showNext() && nextBox != null && nextBox.contains(x, y))
        {
          hover = NEXT;
          return true;
        }

        x -= BORDER;
        y -= pageY;

        hover = page.onMouseMove(x, y);
        if (hover != NONE)
        {
          return true;
        }
      }
    }

    hover = NONE;
    return false;
  }

  @Override
  protected boolean onMouseDown(int x, int y)
  {
    if (x != Integer.MIN_VALUE && y != Integer.MIN_VALUE)
    {
      GC gc = new GC(getCanvas());
      for (int i = 0; i < gearPaths.length; i++)
      {
        Path path = gearPaths[i];
        if (path != null && path.contains(x, y, gc, false))
        {
          if (i != getSelection())
          {
            setSelection(i);
          }

          return true;
        }
      }

      if (exitBox != null && exitBox.contains(x, y))
      {
        exit();
        return true;
      }

      Page page = getSelectedPage();
      if (page != null)
      {
        if (page.showBack() && backBox != null && backBox.contains(x, y))
        {
          setSelection(getSelection() - 1);
          return true;
        }

        if (page.showNext() && nextBox != null && nextBox.contains(x, y))
        {
          setSelection(getSelection() + 1);
          return true;
        }

        x -= BORDER;
        y -= pageY;

        if (page.onMouseDown(x, y))
        {
          return true;
        }
      }
    }

    return false;
  }

  protected void exit()
  {
    hover = EXIT;

    AnimatedCanvas canvas = getCanvas();
    canvas.redraw();

    ExitShell exitShell = new ExitShell(this);
    Boolean result = exitShell.openModal();

    if (Boolean.TRUE.equals(result))
    {
      for (Listener listener : getListeners())
      {
        listener.onExit(GearAnimator.this, getSelectedPage());
      }
    }

    hover = NONE;
    if (!canvas.isDisposed())
    {
      canvas.redraw();
    }
  }

  protected boolean shouldShowOverlay()
  {
    Page page = getSelectedPage();
    if (page instanceof ImagePage)
    {
      ImagePage questionPage = (ImagePage)page;

      if (hover <= CHOICES)
      {
        int hoveredChoice = -hover + CHOICES;
        return hoveredChoice == questionPage.getOverlayChoice();
      }

      int choice = questionPage.getChoice();
      if (choice != NONE)
      {
        return choice == questionPage.getOverlayChoice();
      }
    }

    return (System.currentTimeMillis() / 1000 & 1) == 1;
  }

  @Override
  protected boolean advance()
  {
    boolean needsRedraw = false;
    if (overflow)
    {
      overflow = false;
      needsRedraw = true;
    }

    boolean showOverlay = shouldShowOverlay();
    if (showOverlay != oldShowOverlay)
    {
      oldShowOverlay = showOverlay;
      updatePage();
      needsRedraw = true;
    }

    if (hover != oldHover)
    {
      needsRedraw = true;
    }

    if (speed >= ANGLE)
    {
      startAnimation = 0;
      return needsRedraw;
    }

    long now = System.currentTimeMillis();
    if (startAnimation == 0)
    {
      startAnimation = now;
    }

    long timeSinceStart = now - startAnimation;
    speed = timeSinceStart * ANGLE / 1900;
    angle += speed;
    return true;
  }

  @Override
  protected void paint(GC gc, Image buffer)
  {
    gc.setFont(getBaseFont());
    gc.setLineWidth(3);
    gc.setAntialias(SWT.ON);

    // Unselected gears
    Page page = getSelectedPage();
    int alpha = Math.min((int)(255 * speed / ANGLE), 255);

    for (int i = 0; i < GEARS + 1; i++)
    {
      if (i != selection && (i < GEARS || summaryShown))
      {
        tooltipPoints[i] = paintGear(gc, i, alpha);
      }
    }

    // Selected gear
    tooltipPoints[selection] = paintGear(gc, selection, alpha);

    // Exit button
    int centerX = BORDER + PAGE_WIDTH - exit.getBounds().width / 2;
    int centerY = BORDER + exit.getBounds().height / 2;
    Image exitImage = hover == EXIT ? exitHover : exit;

    exitBox = exitImage.getBounds();
    exitBox.x = centerX - exitImage.getBounds().width / 2;
    exitBox.y = centerY - exitImage.getBounds().height / 2;
    gc.drawImage(exitImage, exitBox.x, exitBox.y);

    // Selected page
    if (!pageBufferUpdated)
    {
      updatePage();
      pageBufferUpdated = true;
    }

    if (oldSelection == NONE)
    {
      gc.setAlpha(alpha);
      gc.drawImage(pageBuffer, BORDER, pageY);
      gc.setAlpha(255);
    }
    else
    {
      double progress = 2 * speed / ANGLE;
      int slide = Math.min((int)(PAGE_WIDTH * progress * progress), PAGE_WIDTH);

      gc.setAlpha(255 - alpha);
      if (selection > oldSelection)
      {
        gc.drawImage(oldPageBuffer, slide, 0, PAGE_WIDTH - slide, PAGE_HEIGHT, BORDER, pageY, PAGE_WIDTH - slide, PAGE_HEIGHT);
        gc.setAlpha(alpha);
        gc.drawImage(pageBuffer, 0, 0, slide, PAGE_HEIGHT, BORDER + PAGE_WIDTH - slide, pageY, slide, PAGE_HEIGHT);
      }
      else
      {
        gc.drawImage(oldPageBuffer, 0, 0, PAGE_WIDTH - slide, PAGE_HEIGHT, BORDER + slide, pageY, PAGE_WIDTH - slide, PAGE_HEIGHT);
        gc.setAlpha(alpha);
        gc.drawImage(pageBuffer, PAGE_WIDTH - slide, 0, slide, PAGE_HEIGHT, BORDER, pageY, slide, PAGE_HEIGHT);
      }

      gc.setAlpha(255);
    }

    // Gear tooltip
    if (hover >= 0 && hover < tooltipPoints.length)
    {
      Point point = tooltipPoints[hover];
      String title = pages[hover].getTitle();

      gc.setFont(tooltipFont);
      gc.setForeground(DARK_GRAY);
      gc.setBackground(tooltipColor);
      Rectangle rectangle = drawText(gc, point.x, point.y + 14, title, 2);

      gc.setForeground(GRAY);
      gc.setLineWidth(1);
      gc.drawRectangle(rectangle);
    }

    // Back button
    if (page.showBack())
    {
      backBox = Animator.drawImage(gc, backImages[hover == BACK ? 1 : 0], BORDER + buttonR, answerY);
    }

    // Next button
    if (page.showNext())
    {
      nextBox = Animator.drawImage(gc, nextImages[hover == NEXT ? 1 : 0], PAGE_WIDTH + BORDER - buttonR, answerY);
    }

    oldHover = hover;
  }

  private Point paintGear(GC gc, int i, int alpha)
  {
    double offset = 2 * i * radius;
    double x = BORDER + radius + offset;
    double y = BORDER + radius;
    double r2 = (double)radius * .8f;
    double r3 = (double)radius * .5f;

    int selected = 0;
    double factor = 1;
    if (i == oldSelection)
    {
      if (speed < ANGLE / 2)
      {
        selected = 1;
      }
    }
    else if (i == selection)
    {
      if (speed >= ANGLE / 2)
      {
        selected = 1;
        factor += (ANGLE - speed) * .02;
      }
      else
      {
        factor += speed * .02;
      }
    }

    boolean hovered = false;
    if (i == hover)
    {
      factor += .1;
      oldHover = hover;
      if (selected == 0)
      {
        hovered = true;
      }
    }

    double outerR = factor * radius;
    double innerR = factor * r2;
    float angleOffset = (angle + i * ANGLE) * (i % 2 == 1 ? -1 : 1);

    gc.setForeground(hovered ? DARK_GRAY : gearForeground[selected]);
    gc.setBackground(hovered ? GRAY : gearBackground[selected]);

    Display display = getDisplay();
    Path path = drawGear(gc, display, x, y, outerR, innerR, angleOffset);

    if (gearPaths[i] != null)
    {
      gearPaths[i].dispose();
    }

    gearPaths[i] = path;

    int ovalX = (int)(x - factor * r3);
    int ovalY = (int)(y - factor * r3);
    int ovalR = (int)(2 * factor * r3);
    gc.setBackground(WHITE);
    gc.fillOval(ovalX, ovalY, ovalR, ovalR);
    gc.drawOval(ovalX, ovalY, ovalR, ovalR);

    if (i == 0)
    {
      Animator.drawImage(gc, welcomeImages[selected], (int)x, (int)y);
    }
    else if (i < GEARS)
    {
      String number = Integer.toString(i);
      gc.setForeground(selected == 1 ? gearForeground[1] : GRAY);
      gc.setFont(numberFont);
      Animator.drawText(gc, x, y - 1, number);
    }
    else
    {
      Animator.drawImage(gc, summaryImages[selected], (int)x, (int)y);
    }

    return paintBadge(gc, x, y, outerR, i, alpha);
  }

  private Point paintBadge(GC gc, double x, double y, double outerR, int i, int alpha)
  {
    if (selection >= GEARS)
    {
      gc.setAlpha(255 - alpha);
    }
    else if (oldSelection >= GEARS)
    {
      gc.setAlpha(alpha);
    }

    Page page = pages[i];
    Answer answer = page.getChoiceAnswer();
    if (answer instanceof ImageAnswer)
    {
      ImageAnswer imageAnswer = (ImageAnswer)answer;
      Image image = imageAnswer.getImages()[4];
      gc.drawImage(image, (int)(x - image.getBounds().width / 2), (int)(y - outerR - 12));
    }

    gc.setAlpha(255);
    return new Point((int)x, (int)(y + outerR));
  }

  private Page updatePage()
  {
    pageGC.setBackground(WHITE);
    pageGC.fillRectangle(pageBuffer.getBounds());

    Page page = getSelectedPage();
    page.paint(pageGC);
    return page;
  }

  void updateOverlay(int x, int y)
  {
    Page page = getSelectedPage();
    if (page instanceof ImagePage)
    {
      ImagePage questionPage = (ImagePage)page;
      questionPage.overlayX += x;
      questionPage.overlayY += y;

      System.out.println("" + questionPage.overlayX + ", " + questionPage.overlayY);

      updatePage();
      overflow = true;
    }
  }

  private static Path drawGear(GC gc, Display display, double cx, double cy, double outerR, double innerR, float angleOffset)
  {
    double radian2 = ANGLE / 2 * RADIAN;
    double radian3 = .06;

    Path path = new Path(display);

    for (int i = 0; i < TEETH; i++)
    {
      double radian = (i * ANGLE + angleOffset) * RADIAN;

      double x = cx + outerR * Math.cos(radian);
      double y = cy - outerR * Math.sin(radian);

      if (i == 0)
      {
        path.moveTo((int)x, (int)y);
      }

      double r1 = radian + radian3;
      double r3 = radian + radian2;
      double r2 = r3 - radian3;
      double r4 = r3 + radian2;

      x = cx + innerR * Math.cos(r1);
      y = cy - innerR * Math.sin(r1);
      path.lineTo((int)x, (int)y);

      x = cx + innerR * Math.cos(r2);
      y = cy - innerR * Math.sin(r2);
      path.lineTo((int)x, (int)y);

      x = cx + outerR * Math.cos(r3);
      y = cy - outerR * Math.sin(r3);
      path.lineTo((int)x, (int)y);

      x = cx + outerR * Math.cos(r4);
      y = cy - outerR * Math.sin(r4);
      path.lineTo((int)x, (int)y);
    }

    path.close();
    gc.fillPath(path);
    gc.drawPath(path);
    return path;
  }

  /**
   * @author Eike Stepper
   */
  public interface Listener
  {
    public void onAnswer(GearAnimator animator, Page page, Answer answer);

    public void onExit(GearAnimator animator, Page page);
  }

  /**
   * @author Eike Stepper
   */
  public abstract class Answer
  {
    public Answer()
    {
    }

    public abstract Point getSize(GC gc, Page page);

    public abstract Rectangle paint(GC gc, Page page, int index, int x, int y, boolean hovered, boolean selected);
  }

  /**
   * @author Eike Stepper
   */
  public class TextAnswer extends Answer
  {
    private final String text;

    public TextAnswer(String text)
    {
      this.text = text;
    }

    public final String getText()
    {
      return text;
    }

    @Override
    public Point getSize(GC gc, Page page)
    {
      gc.setFont(hoverFont);
      return gc.stringExtent(text);
    }

    @Override
    public Rectangle paint(GC gc, Page page, int index, int x, int y, boolean hovered, boolean selected)
    {
      gc.setFont(hovered ? hoverFont : bigFont);
      gc.setForeground(selected ? purple : DARK_GRAY);

      Point extent = gc.stringExtent(text);
      x -= extent.x / 2 - 60; // TODO -60 is a hack!
      y -= extent.y / 2;
      gc.drawText(text, x, y, true);

      return new Rectangle(x, y, extent.x, extent.y);
    }
  }

  /**
   * @author Eike Stepper
   */
  public class ImageAnswer extends Answer
  {
    private final Image[] images;

    public ImageAnswer(Image... images)
    {
      this.images = images;
    }

    public final Image[] getImages()
    {
      return images;
    }

    @Override
    public Point getSize(GC gc, Page page)
    {
      Rectangle bounds = images[2].getBounds();
      return new Point(bounds.width, bounds.height);
    }

    @Override
    public Rectangle paint(GC gc, Page page, int index, int x, int y, boolean hovered, boolean selected)
    {
      Image image = images[0];
      if (hovered)
      {
        image = images[2];
      }
      else if (selected)
      {
        image = images[1];
      }
      else
      {
        if (page instanceof ImagePage && images.length > 3)
        {
          int overlayChoice = ((ImagePage)page).getOverlayChoice();
          boolean overlayChoiceYes = overlayChoice == index;
          boolean showOverlay = shouldShowOverlay();

          if (showOverlay == overlayChoiceYes)
          {
            image = images[3];
          }
        }
      }

      return Animator.drawImage(gc, image, x, y);
    }
  }

  /**
   * @author Eike Stepper
   */
  public class BackButton extends ImageAnswer
  {
    public BackButton()
    {
      super(backImages);
    }
  }

  /**
   * @author Eike Stepper
   */
  public class NextButton extends ImageAnswer
  {
    public NextButton()
    {
      super(nextImages);
    }
  }

  /**
   * @author Eike Stepper
   */
  public abstract class Page
  {
    private final int index;

    private final String title;

    private Answer[] answers;

    private Rectangle[] answerBoxes;

    private int choice = NONE;

    public Page(int index, String title)
    {
      this.index = index;
      this.title = title;
    }

    public final int getIndex()
    {
      return index;
    }

    public final String getTitle()
    {
      return title;
    }

    public final Answer[] getAnswers()
    {
      return answers;
    }

    public final void setAnswers(Answer[] answers)
    {
      this.answers = answers;
      answerBoxes = new Rectangle[answers.length];
    }

    public final int getAnswer(int x, int y)
    {
      for (int i = 0; i < answers.length; i++)
      {
        Rectangle box = answerBoxes[i];
        if (box != null && box.contains(x, y))
        {
          return i;
        }
      }

      return NONE;
    }

    public final Answer getChoiceAnswer()
    {
      return choice == NONE ? null : answers[choice];
    }

    public final int getChoice()
    {
      return choice;
    }

    public final void setChoice(int choice)
    {
      this.choice = choice;
    }

    protected void dispose()
    {
    }

    protected boolean showBack()
    {
      return index > 0;
    }

    protected boolean showNext()
    {
      return index < GEARS;
    }

    protected int onMouseMove(int x, int y)
    {
      int i = getAnswer(x, y);
      if (i != NONE)
      {
        pageBufferUpdated = false;
        return CHOICES - i;
      }

      if (hover <= CHOICES)
      {
        pageBufferUpdated = false;
      }

      return NONE;
    }

    protected boolean onMouseDown(int x, int y)
    {
      int i = getAnswer(x, y);
      if (i != NONE)
      {
        doAnswer(i);
        return true;
      }

      return false;
    }

    protected final void paint(GC gc)
    {
      String title = getTitle();

      Font oldFont = gc.getFont();
      gc.setFont(bigFont);

      Point extent = gc.stringExtent(title);
      gc.setForeground(purple);
      gc.drawText(title, (PAGE_WIDTH - extent.x) / 2, 0, true);

      gc.setFont(oldFont);

      paintContent(gc);
      paintAnswers(gc);
    }

    protected abstract void paintContent(GC gc);

    protected int getAnswerY()
    {
      return answerY;
    }

    private void doAnswer(int i)
    {
      Answer answer = answers[i];

      if (i == choice)
      {
        hover = NONE;
        choice = NONE;
        answer = null;
      }
      else
      {
        setChoice(i);
      }

      updatePage();

      for (Listener listener : getListeners())
      {
        listener.onAnswer(GearAnimator.this, this, answer);
      }

      if (answer != null)
      {
        int selection = getSelection();
        if (selection < GEARS)
        {
          setSelection(selection + 1);
        }
      }
    }

    private void paintAnswers(GC gc)
    {
      boolean selecteds[] = new boolean[answers.length];
      boolean hovereds[] = new boolean[answers.length];
      Point sizes[] = new Point[answers.length];

      int width = (answers.length - 1) * BORDER;
      int height = 0;

      for (int i = 0; i < answers.length; i++)
      {
        selecteds[i] = i == choice;
        if (CHOICES - i == hover)
        {
          oldHover = hover;
          hovereds[i] = true;
        }

        sizes[i] = answers[i].getSize(gc, this);
        width += sizes[i].x;
        height = Math.max(height, sizes[i].y);
      }

      int x = (PAGE_WIDTH - width) / 2;
      int y = getAnswerY() - pageY;

      for (int i = 0; i < answers.length; i++)
      {
        Answer answer = answers[i];
        answerBoxes[i] = answer.paint(gc, this, i, x, y, hovereds[i], selecteds[i]);
        x += BORDER + sizes[i].x;
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  public class ImagePage extends Page
  {
    private final Image image;

    private final Image overlay;

    private final int overlayChoice;

    private int overlayX;

    private int overlayY;

    public ImagePage(int index, String title, int overlayChoice, int overlayX, int overlayY, Answer... answers)
    {
      super(index, title);
      this.overlayChoice = overlayChoice;
      setAnswers(answers);

      Display display = getDisplay();
      image = doLoadImage(display, index, "");
      overlay = doLoadImage(display, index, "_ovr");

      this.overlayX = overlayX;
      this.overlayY = overlayY;
    }

    public ImagePage(int index, String title, int overlayChoice, int overlayX, int overlayY)
    {
      this(index, title, overlayChoice, overlayX, overlayY, new Answer[] { new ImageAnswer(yesImages), new ImageAnswer(noImages) });
    }

    public final int getOverlayChoice()
    {
      return overlayChoice;
    }

    @Override
    protected void paintContent(GC gc)
    {
      if (image != null)
      {
        Rectangle bounds = image.getBounds();
        int x = (PAGE_WIDTH - bounds.width) / 2;
        int y = (PAGE_HEIGHT - bounds.height) / 2;
        gc.drawImage(image, x, y);

        if (overlay != null && shouldShowOverlay())
        {
          gc.drawImage(overlay, x + overlayX, y + overlayY);
        }
      }
    }

    private Image doLoadImage(final Display display, int index, String suffix)
    {
      try
      {
        return loadImage("page" + index + suffix + ".png");
      }
      catch (Exception ex)
      {
        return null;
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  public class PreferencePage extends ImagePage
  {
    private final URI preferenceKey;

    private final String yesValue;

    private final String noValue;

    public PreferencePage(int index, String title, int overlayChoice, int overlayX, int overlayY, String preferenceKey, String yesValue, String noValue)
    {
      super(index, title, overlayChoice, overlayX, overlayY, new Answer[] { new ImageAnswer(yesImages), new ImageAnswer(noImages) });
      this.preferenceKey = PreferencesFactory.eINSTANCE.createURI(preferenceKey);
      this.yesValue = yesValue;
      this.noValue = noValue;
    }

    public PreferencePage(int index, String title, int overlayChoice, int overlayX, int overlayY, String preferenceKey)
    {
      this(index, title, overlayChoice, overlayX, overlayY, preferenceKey, "true", "false");
    }

    public final URI getPreferenceKey()
    {
      return preferenceKey;
    }

    public final String getYesValue()
    {
      return yesValue;
    }

    public final String getNoValue()
    {
      return noValue;
    }
  }

  /**
   * @author Eike Stepper
   */
  public class SummaryPage extends Page
  {
    private Rectangle[] boxes;

    public SummaryPage(int index, String title)
    {
      super(index, title);
      setAnswers(new Answer[] { new TextAnswer("Finish") });
    }

    @Override
    protected boolean showNext()
    {
      return false;
    }

    @Override
    protected int onMouseMove(int x, int y)
    {
      if (boxes != null)
      {
        for (int i = 0; i < boxes.length; i++)
        {
          Rectangle box = boxes[i];
          if (box.contains(x, y))
          {
            return i + 1;
          }
        }
      }

      return super.onMouseMove(x, y);
    }

    @Override
    protected boolean onMouseDown(int x, int y)
    {
      if (boxes != null)
      {
        for (int i = 0; i < boxes.length; i++)
        {
          Rectangle box = boxes[i];
          if (box.contains(x, y))
          {
            setSelection(i + 1);
            return true;
          }
        }
      }

      return super.onMouseDown(x, y);
    }

    @Override
    protected void paintContent(GC gc)
    {
      gc.setFont(normalFont);

      boxes = new Rectangle[GEARS - 1];
      int offsetX = yesImages[4].getBounds().width + 12;
      int minWidth = Integer.MAX_VALUE;
      int maxWidth = 0;

      for (int i = 1; i < GEARS; i++)
      {
        Page page = pages[i];
        Point extent = gc.stringExtent(page.getTitle());
        int width = extent.x;
        minWidth = Math.min(minWidth, width);
        maxWidth = Math.max(maxWidth, width);

        boxes[i - 1] = new Rectangle(0, 0, offsetX + width, extent.y + 4);
      }

      int width = (minWidth + maxWidth) / 2 + offsetX;

      for (int i = 1; i < GEARS; i++)
      {
        int x = (PAGE_WIDTH - width) / 2;
        int y = 40 * (1 + i);

        ImagePage page = (ImagePage)pages[i];
        ImageAnswer answer = (ImageAnswer)page.getChoiceAnswer();
        if (answer != null)
        {
          gc.drawImage(answer.images[4], x, y + 8);
          gc.setForeground(purple);
        }
        else
        {
          gc.drawImage(question, x, y + 8);
          gc.setForeground(DARK_GRAY);
        }

        String title = page.getTitle();
        if (title.endsWith("?"))
        {
          title = title.substring(0, title.length() - 1);
        }

        gc.drawText(title, x + offsetX, y);
        boxes[i - 1].x = x;
        boxes[i - 1].y = y + 4;
      }
    }
  }
}
