package com.Series40Book.SessionViewer2;

import com.Series40Book.Util.Fetch;
import com.Series40Book.HttpClient.*;

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.HttpConnection;

public class PhotoViewer extends MIDlet {

  public static Display display;
  private static PhotoViewer controller;

  public static String url;
  public static HttpClient httpClient;

  public PhotoViewer () {
    display = Display.getDisplay(this);
    controller = this;

    url = getAppProperty ("PhotoServerURL");
    httpClient = new HttpClient ();
    httpClient.setUrl (url);
    httpClient.setRequestMethod (HttpConnection.POST);
    try {
      CookieHandler ch = new CookieHandler ();
      httpClient.addHandler (ch);
    } catch (Exception e) {
      e.printStackTrace ();
    }
  }

  protected void startApp () {
    Form view = new View ("Photo Viewer");
    view.append ("Select Next to start");
    display.setCurrent (view);
  }

  protected void pauseApp () {
    // Do nothing
  }

  protected void destroyApp (boolean unconditional) {
    // Do nothing
  }

  public static void exit () {
    controller.destroyApp (true);
    controller.notifyDestroyed ();
  }

  public static void getNext () {
    Canvas screen = new AnimatedWait (url);
    display.setCurrent (screen);
  }

  public static void showPhoto(String title,
              String description, Image img,
              boolean isSuccessful) {

    Form view = new View(title);
    if (isSuccessful) {
      view.append(new ImageItem(description, img,
          ImageItem.LAYOUT_CENTER, ""));
    } else {
      view.append(new StringItem("Status",
          "The network is NOT available"));
    }

    display.setCurrent(view);
  }
}

class View extends Form
        implements CommandListener {

  private Command next, exit;

  public View (String title) {
    super (title);

    next = new Command ("Next", Command.SCREEN, 1);
    exit = new Command ("Exit", Command.EXIT, 1);
    addCommand (next);
    addCommand (exit);
    setCommandListener (this);
  }

  public void commandAction (Command c, Displayable d) {
    if (c == exit) {
      PhotoViewer.exit ();
    } else if (c == next) {
      PhotoViewer.getNext ();
    }
  }
}

class FetchWorker extends Fetch implements Runnable {

  public AnimatedWait wait;
  private int count = 0;

  public FetchWorker (String url) {
    super (url);
  }

  protected void updateWaitStatus () {
    count++;
    wait.setCount(count);
  }

  public void run () {
    getNext (PhotoViewer.httpClient);
    PhotoViewer.showPhoto (
        title, description, img, isSuccessful);
  }
}

class AnimatedWait extends Canvas 
                    implements CommandListener {

  private int maxCount = 10;
  private int count = 0;
  private Command exit;

  private Image img;
  private String url;
  private FetchWorker worker;

  public AnimatedWait (String url) {
    this.url = url;
    worker = null;

    try {
      img = Image.createImage("/" + "wait.png");
    } catch (Exception e) {
      e.printStackTrace ();
      img = null;
    }
    exit = new Command ("Exit", Command.EXIT, 1);
    addCommand (exit);
    setCommandListener (this);
  }

  public void setCount (int value) {
    count = value % maxCount;
    repaint ();
    serviceRepaints ();
  }

  public void commandAction (Command c, Displayable d) {
    if (c == exit) {
      PhotoViewer.exit ();
    }
  }

  public void paint (Graphics g) {

    int width = getWidth ();
    int height = getHeight ();

    g.setColor(0xffffff);
    g.fillRect(0,  0, width, height);
    g.setColor(0x000000);

    g.drawImage (img, width / 2, height / 2,
            Graphics.HCENTER | Graphics.VCENTER);

    int buffer = 10; // Pixels at both ends of the bar

    int endX = buffer +
          ((width - (2 * buffer)) * count / maxCount);
    g.setColor(0, 0, 255);
    int startY = height * 2 / 3;
    g.fillRect(buffer, startY,
               endX-buffer, 15);

    if (worker == null) {
      worker = new FetchWorker(url);
      // The worker updates the current screen
      worker.wait = this;
      Thread t = new Thread(worker);
      t.start();
    }
    return;
  }
}