/* Dali Clock - a melting digital clock for Palm WebOS.
 * Copyright (c) 1991-2009 Jamie Zawinski <jwz@jwz.org>
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation.  No representations are made about the suitability of this
 * software for any purpose.  It is provided "as is" without express or
 * implied warranty.
 */


function ClockAssistant() {
}


// For setup tasks that have to happen when the scene is first created.
//
ClockAssistant.prototype.setup = function() {

  // Default settings
  //
  this.model = {
    time_mode:    'HHMMSS',
    date_mode:    'MMDDYY',
    twelve_hour_p: true,
    fps:           12,
    cps:           8,
  };

  // Load the Preferences cookie.
  //
  this.prefs = new Mojo.Model.Cookie("Preferences"); 
  var op = this.prefs.get();
  if (op) {
    for (var key in this.model) {
      if (op[key] != undefined) this.model[key] = op[key];
    }
  }

  // These are not restored from prefs.
  //
  this.model.orientation  = 'up';
  this.model.show_date_p  = false;
  this.model.vp_scaling_p = false;  // Works in Palm Host, not on Pre.
  this.model.debug_digit  = undefined;

  var screen_w = window.innerWidth;   // 320
  var screen_h = window.innerHeight;  // 452

  // move the canvas up slightly to compensate for the junk at the
  // bottom of the screen.
  this.model.width  = screen_w - 2;   // 318
  this.model.height = screen_h - 32;  // 420

  var bdiv   = document.getElementById ("clockbg");
  var canvas = document.getElementById ("canvas");

  bdiv.style.width    = screen_w + 'px';
  bdiv.style.height   = screen_h + 'px';
  canvas.style.width  = this.model.width  + 'px';
  canvas.style.height = this.model.height + 'px';

/*
  var bd = 10;
  canvas.style.left = bd + 'px';
  canvas.style.top  = bd + 'px';
  canvas.style.width  = (this.model.width - bd - bd)  + 'px';
  canvas.style.height = (this.model.height - bd - bd) + 'px';
*/

  // Initialize the clock code in daliclock.js.
  //
  this.clock = new DaliClock();
  this.clock.setup (canvas, bdiv, this.load_fonts());
  this.clock.changeSettings (this.model);

  // Bind taps to show the date.
  //
  Mojo.Event.listen (bdiv,   Mojo.Event.tap, this.date_tap.bind(this));
  Mojo.Event.listen (canvas, Mojo.Event.tap, this.date_tap.bind(this));

  // Handle keyboard, for debugging.
  //
  document.observe('keypress', this.keypress.bindAsEventListener(this));

  // Set up the App menu.
  //
  this.controller.setupWidget(Mojo.Menu.appMenu,
    { omitDefaultItems: true },
    { visible: true,
      items: [ {label: "About Dali Clock...", command: 'doAbout' },
               //Mojo.Menu.editItem,
               {label: "Preferences...", command: 'doPrefs' },
               //{label: "Help...", command: 'doHelp', disabled: true }
             ]});

  // Deactivate the clock when the app itself is hidden, too.
  //
  this.controller.listen (this.controller.sceneElement,
                          Mojo.Event.stageActivate,
                          this.activate.bindAsEventListener(this));
  this.controller.listen (this.controller.sceneElement,
                          Mojo.Event.stageDeactivate,
                          this.deactivate.bindAsEventListener(this));
}


// For setup tasks that have to happen each time the scene is activated.
//
ClockAssistant.prototype.activate = function() {
  this.clock.show();
}


// Called when the prefs dialog is closed.
//
ClockAssistant.prototype.save_prefs = function() {
  // Save the prefs cookie, and inform the clock of the new settings.
  this.prefs.put (this.model);
  this.clock.changeSettings (this.model);
}


// Tasks that have to happen each time the scene is deactivated.
// Note that by default, this is only called when this page is
// occluded by another page within this application -- it is not
// called when the app itself is hidden unless we bind the
// controller's "stageDeactivate" event to it as well.
//
ClockAssistant.prototype.deactivate = function() {
  this.clock.hide();
}


// About to exit.
//
ClockAssistant.prototype.cleanup = function() {
  this.save_prefs();
  this.clock.cleanup();
}


ClockAssistant.prototype.orientationChanged = function(orient) {
  this.model.orientation = orient;
  this.clock.changeSettings (this.model);
}


ClockAssistant.prototype.date_tap = function(event) {
  this.model.show_date_p = true;
  this.clock.changeSettings (this.model);
  // turn off the date display in 2 seconds.
  window.setTimeout (this.date_untap.bind(this), 2000);
}


ClockAssistant.prototype.date_untap = function(event) {
  this.model.show_date_p = false;
  this.clock.changeSettings (this.model);
}


ClockAssistant.prototype.keypress = function(event) {

  var key = String.fromCharCode(event.charCode).toLowerCase();
  if (! key) return;
  if (key == ' ') {
    return this.date_tap (event);
  } else if (key >= '0' && key <= '9') {
    key = key - '0';
  } else {
    key = { 'e':1, 'r':2, 't':3,  // in case keypad not in numeric-mode.
            'd':4, 'f':5, 'g':6,
            'x':7, 'c':8, 'v':9,
            '@':0, '\b':-1,
          }[key];
  }
  if (key != undefined) {
    this.model.debug_digit = key;
    this.clock.changeSettings (this.model);
    this.model.debug_digit = undefined;
  }
}



// Called when something is selected from the App menu.
//
ClockAssistant.prototype.handleCommand = function(event) {
  if (event.type == Mojo.Event.command) {	
    switch (event.command) {
      case 'doAbout':
        var title   = Mojo.Controller.appInfo.title;
        var version = Mojo.Controller.appInfo.version;
        var vendor  = Mojo.Controller.appInfo.vendor;
        var email   = Mojo.Controller.appInfo.vendor_email;
        var url     = Mojo.Controller.appInfo.vendor_url;
        var date    = Mojo.Controller.appInfo.release_date;
        var year    = date.replace (new RegExp('^.*[- ]([0-9]{4})$'), '$1');
        year = '1991-' + year;
        var body    = ('<div align=center>' +
                       'Copyright &copy; ' + year + '<BR>' +
                       vendor + ' &lt;' + 
                       '<A HREF="mailto:' + email + '">' + email + 
                       '</A>&gt;<BR><BR>' +
                       '<A HREF="' + url + '">' + url + '</A>' +
                       '</div>'
                       );
        title = '<div align=center>' + title + ' ' + version + '</div>';

        this.controller.showAlertDialog({
          onChoose: function(value) {},
          title:title,
          message:body,
          choices:[ {label:'OK', value:'OK', type:'color'} ]});
        break;
      case 'doPrefs':
        Mojo.Controller.stageController.pushScene ("prefs", 
                                                   this.model,
                                                   this.save_prefs.bind(this));
      break;
    }
  }
}


ClockAssistant.prototype.load_fonts = function() {

  var fonts = new Array();
  var i = 0;

  while (true) {
    var path = Mojo.appPath + "images/font" + i + ".json";
    var font = Mojo.loadJSONFile (path);
    if (! font) break;
    fonts[i++] = font;
  }

  return fonts;
}
