<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Water Tracker"
            title_url="http://www.bottledwaterblues.com/Better_Drinking_Habits.cfm"
            description="Keep track of how much water you drink a day and monitor your progress."
            author="Daniel L."
            author_location="Mountain View, CA"
            author_email="daniel.feedback+watertracker@gmail.com"
            author_affiliation="Google Inc."
            category="lifestyle"
            screenshot="/ig/modules/water_tracker.png"
            thumbnail="/ig/modules/water_tracker-thm.png"
            height="210">
  <Require feature="setprefs"/>
  <Require feature="dynamic-height"/>
  <Require feature="analytics"/>
</ModulePrefs>
<UserPref name="cupCnt"
          display_name="Number of cups?"
          datatype="enum"
          default_value="8">
  <EnumValue value="8" />
  <EnumValue value="9" />
  <EnumValue value="10" />
  <EnumValue value="11" />
  <EnumValue value="12" />
  <EnumValue value="13" />
  <EnumValue value="14" />
  <EnumValue value="15" />
</UserPref>
<UserPref name="jsonPref"
          datatype="hidden"
          default_value="" />
<Content type="html">
<![CDATA[
<style type="text/css">
#infoBlock {
  font-size: 0.7em;
}

#descBlock {
  color: #676767;
  font-size: 0.7em;
  border-bottom: 2px dotted #BBB;
  padding: 2px 3px;
  display: none;
}
#descBlock table {
  color: #676767;
  font-size: 0.95em;
  margin: 0px;
}
#descBlock tr {
  margin: 0px;
  padding: 0px;
}
#descBlock .labelCol {
  text-align: right;
  padding-right: 10px;
}

#waterTableBlock td {
  text-align: center;
  white-space: nowrap;
  padding: 3px 5px;
}
#waterTableBlock img {
  cursor: pointer;
}

.chkLabel {
  width: 50px;
  margin: 0px auto;
  font-size: 0.7em;
}
</style>

<div id="infoBlock">
  <div id="statusLabel"></div>
  <a id="infoLink" href="javascript:void(0);">Show Info</a> |
  <a id="statLink" href="javascript:void(0);">Show Stats</a> |
  <a id="resetLink" href="javascript:void(0);">Reset Stats</a>
</div>

<div id="descBlock"></div>
<div id="waterTableBlock"></div>


<script type="text/javascript">
var prefs = new _IG_Prefs();

/******************
  Water Tracker JSON object.
  Contains properties to save water tracker progress.
  Uses JSON to save properties into single hidden UserPref field.
*******************/
var WTUP = {
  cupChkCsv : "",
  currentDate : new Date(),
  startDate : new Date(),
  completedDays : 0,
  flag : false,

  showPrefs : function() {
    var show = new Array();
    for (property in this) {
      if (typeof(this[property]) != "function") {
        show.push(property + "=" + this[property]);
      }
    }
    alert(show.join("\n"));
  },

  loadPrefs : function() {
    var jsonPref = prefs.getString("jsonPref");

    if (jsonPref != "") {
      //Retrieve user pref values
      var obj = eval("(" + jsonPref + ")");

      this.cupChkCsv = obj.cupChkCsv;
      this.currentDate = (new Date(obj.currentDate)) ? new Date(obj.currentDate) : new Date();
      this.startDate = (new Date(obj.startDate)) ? new Date(obj.startDate) : new Date();
      this.completedDays = isNaN(obj.completedDays) ? 0 : obj.completedDays;
      this.flag = obj.flag;
    } else {
      this.savePrefs();
    }
  },

  savePrefs : function() {
    var json = new Array();
    for (var property in this) {
      switch (this[property].constructor) {
      case String:
        json.push(property + ' : "' + this[property] + '"');
        break;

      case Number:
      case Boolean:
        json.push(property + " : " + this[property]);
        break;

      case Date:
        json.push(property + " : " + Date.parse(this[property]));
        break;
      }
    }

    prefs.set("jsonPref", "{" + json.join(",\n") + "}");
  }
}



/******************
  Water Tracker object.
*******************/
var WT = {
  Prefs : WTUP,  //Reference JSON UserPref object
  cupCnt : 0,
  images : null,

  emptyImg : _IG_GetImage("http://www.google.com/ig/modules/water_tracker_content/empty.gif"),
  fullImg : _IG_GetImage("http://www.google.com/ig/modules/water_tracker_content/full.gif"),

  infoLinkText : ["Show Info", "Hide Info"],
  statLinkText : ["Show Stats", "Hide Stats"],

  loadWT : function() {
    //Retrieve UserPref values
    this.cupCnt = prefs.getInt("cupCnt");
    this.Prefs.loadPrefs();

    //Paint water tracker table.
    this.drawTable();

    //Tracker should be reset daily. Check if tracker needs to be reset.
    if (!isEqual(this.Prefs.currentDate, new Date())) {
      this.Prefs.flag = false;
      this.Prefs.currentDate = new Date();
      this.saveProgress();
    } else {
      this.restoreProgress();
    }

    //Add event handlers to HTML objects
    _gel("infoLink").onclick = this.Handler.clickInfoLink;
    _gel("statLink").onclick = this.Handler.clickStatLink;
    _gel("resetLink").onclick = this.Handler.clickResetLink;
  },

  saveProgress : function() {
    var cupChkArr = new Array();
    for (var n = 0; n < this.images.length; n++) {
      if (this.images[n].src == this.emptyImg.src) {
        this.images[n].nextSibling.innerHTML = "empty";
        cupChkArr.push(n);
      } else {
        this.images[n].nextSibling.innerHTML = "full";
      }
    }
    this.Prefs.cupChkCsv = cupChkArr.join(",");

    //If all water cups are checked, then increment completed days count.
    var html = ["You drank " + cupChkArr.length + " / " + this.cupCnt + " cups today."];
    if (cupChkArr.length == this.cupCnt) {
      html.push('<span style="font-weight: bold;">Great Job!!!</span>');
      if (!this.Prefs.flag) {
        this.Prefs.flag = true;
        this.Prefs.completedDays++;
        this.refreshStatDesc();
      }
    }
    else if (this.Prefs.flag && cupChkArr.length != this.cupCnt) {
      this.Prefs.flag = false;
      this.Prefs.completedDays--;
      this.refreshStatDesc();
    }
    _gel("statusLabel").innerHTML = html.join("");

    //Save JSON object back into UserPref.
    this.Prefs.savePrefs();
  },

  restoreProgress : function() {
    //Restores checkbox state for each water item.
    var cupChkArr = (this.Prefs.cupChkCsv != "") ? this.Prefs.cupChkCsv.split(",") : [];
    for (var n=0; n<cupChkArr.length; n++) {
      if (cupChkArr[n] < this.images.length) {
        this.images[cupChkArr[n]].src = this.emptyImg.src;
      }
    }

    this.saveProgress();
  },

  resetProgress : function() {
    for (var n=0; n<this.images.length; n++) {
      this.images[n].src = this.fullImg.src;
    }

    this.Prefs.cupChkCsv = "";
    this.Prefs.currentDate = new Date();
    this.Prefs.startDate = new Date();
    this.Prefs.completedDays = 0;
    this.Prefs.flag = false;
    this.refreshStatDesc();
    this.saveProgress();
  },

  drawTable : function() {
    var html = new Array();
    html.push('<table border=0 cellpadding=0 cellspacing=0 width="100%">');
    html.push('<tr>');
    for (var n=0; n<this.cupCnt; ) {
      html.push('<td>');
      html.push('<img onclick="WT.Handler.clickWaterItem(' + n + ');" src="' + this.fullImg.src + '" alt="8oz. glass of water" />')
      html.push('<div class="chkLabel"></div>');
      html.push('</td>');
      n++;

      if (n % 3 == 0) {
        html.push('</tr><tr>');
      }
    }
    html.push('</tr>');
    html.push('</table>');

    var div = _gel("waterTableBlock");
    div.innerHTML = html.join("");
    this.images = div.getElementsByTagName("img");  //store collection of images

    // Dynamic height resizing
    _IG_AdjustIFrameHeight();
  },

  refreshStatDesc : function(name) {
    //If stats are currently displayed, then refresh stats.
    var statLink = _gel("statLink");
    if (statLink.innerHTML == this.statLinkText[1]) {
      this.toggleDesc("stat", true);
    }
  },

  toggleDesc : function(name, show) {
    var infoLink = _gel("infoLink");
    var statLink = _gel("statLink");
    var descBlock = _gel("descBlock");

    switch (name) {
    case "info":
      statLink.innerHTML = this.statLinkText[0];
      if (show) {
        //Generate content
        var descText = [
          'Peope are supposed to drink at least 64 oz. of water each day.',
          'Keep track of how much water you drink!',
          '<br /><br />',
          'Each cup represents 8 oz. of water. Try to drink at least 8 cups a day.',
          'Click on the cups to keep track of your progress.'
        ].join("");

        infoLink.innerHTML = this.infoLinkText[1];
        descBlock.innerHTML = descText;
        descBlock.style.display = "block";
      } else {
        infoLink.innerHTML = this.infoLinkText[0];
        descBlock.style.display = "none";
      }
      break;

    case "stat":
      infoLink.innerHTML = this.infoLinkText[0];
      if (show) {
        //Generate content
        var descText = [
          '<table border=0 cellpadding=0 cellspacing=0 width=100%>',
          '<tr>',
          '<td class="labelCol">Today:</td>',
          '<td>' + this.Prefs.currentDate.toDateString() + '</td>',
          '</tr>',
          '<tr>',
          '<td class="labelCol">Started:</td>',
          '<td>' + this.Prefs.startDate.toDateString() + '</td>',
          '</tr>',
          '<tr>',
          '<td class="labelCol">Total Days:</td>',
          '<td>' + this.getTotalDays() + '</td>',
          '</tr>',
          '<tr>',
          '<td class="labelCol">Completed Days:</td>',
          '<td>' + this.Prefs.completedDays + '</td>',
          '</tr>',
          '<tr>',
          '<td class="labelCol">Percentage:</td>',
          '<td>' + this.getCompletedPercent() + ' %</td>',
          '</tr>',
          '</table>'
        ].join("");

        statLink.innerHTML = this.statLinkText[1];
        descBlock.innerHTML = descText;
        descBlock.style.display = "block";
      } else {
        statLink.innerHTML = this.statLinkText[0];
        descBlock.style.display = "none";
      }
      break;
    }

    // Dynamic height resizing
    _IG_AdjustIFrameHeight();
  },

  getTotalDays : function() {
    //Number of milliseconds in one day
    var ONE_DAY = 1000 * 60 * 60 * 24;
    var currentMs = this.Prefs.currentDate.getTime();
    var startMs = this.Prefs.startDate.getTime();
    return Math.round((currentMs - startMs + ONE_DAY) / ONE_DAY);
  },

  getCompletedPercent : function() {
    return Math.round((this.Prefs.completedDays / this.getTotalDays()) * 10000) / 100;
  },


  /*************
    Handler contains all event handler functions.
  **************/
  Handler : {
    clickInfoLink : function(event) {
      var infoLink = _gel("infoLink");
      WT.toggleDesc("info", infoLink.innerHTML == WT.infoLinkText[0]);
    },

    clickStatLink : function(event) {
      var statLink = _gel("statLink");
      WT.toggleDesc("stat", statLink.innerHTML == WT.statLinkText[0]);
    },

    clickResetLink : function(event) {
      if (confirm("Warning!!!\n\nAll progress and stats will be lost.\nAre you sure you want to reset?")) {
        WT.resetProgress();
      }
    },

    clickWaterItem : function(index) {
      WT.images[index].src = (WT.images[index].src == WT.fullImg.src) ? WT.emptyImg.src : WT.fullImg.src;
      WT.saveProgress();
    }
  }
};

function isEqual(date1, date2) {
  return (date1.getMonth() == date2.getMonth()) &&
        (date1.getDate() == date2.getDate()) &&
        (date1.getFullYear() == date2.getFullYear());
}

_IG_RegisterOnloadHandler(WT.loadWT());
_IG_Analytics("UA-676947-9", "/water_tracker")
</script>
]]>
</Content>
</Module>
