lastHeight = 0;
lastWidth = 0;
timers = {};
config = appNotification.getConfig();

window.addEventListener("load", function() {
  document.body.style.width = config.width + "px";
});

window.addEventListener("unload", function() {
  appNotification.closed(false);
});

window.addEventListener("message", function(e) {
  var cmd = e.data[0];
  console.log('onmessage', e.data);
  if (cmd == 'hi') {
    var child = document.body.firstChild;
    while (child) {
      if (child.nodeName == "DIV") {
        child.firstChild.contentWindow.postMessage(["id", parseInt(child.id)], "*");
      }
      child = child.nextSibling;
    }
  } else if (cmd == 'size') {
    HandleResize();
  } else if (cmd == 'keep') {
    HandleKeepOpen(e.data[1]);
  } else if (cmd == 'close') {
    HandleClose(e.data[1], e.data[2]);
  } else if (cmd == 'click') {
    appNotification.clicked(e.data[1]);
  }
});

appWindow.setExtraPixels(0, config.height);

// Called whenever the frame's contentWindow changes size.
// onSizeChange adds the frame's delta into the total height
function HandleResize() {
  console.debug("HandleResize()");
  var heightDelta = document.body.clientHeight - lastHeight;
  var widthDelta = document.body.clientWidth - lastWidth;

  lastHeight = document.body.clientHeight;
  lastWidth = document.body.clientWidth;

  if (heightDelta || widthDelta) {
    appWindow.resizeTo(lastWidth, lastHeight, true);
  }
}

function HandleClose(id, userClosed) {
  element = document.getElementById(id);
  if (element) {
    appNotification.closed(id, userClosed);
    element.parentNode.removeChild(element);
    HandleResize();
  }
  HandleRemoveTimeout(id);
}

function HandleKeepOpen(id) {
  var e = document.getElementById(id);
  if (e) {
    e.onmouseout = null;
    e.onmouseover = null;
  }
  HandleRemoveTimeout(id);
}

function HandleSuspendTimeout(id) {
  if (id in timers) {
    var data = timers[id];
    if (data.timerId) {
      clearTimeout(data.timerId);
      data.timerId = 0;
    }
  }
}

function HandleResumeTimeout(id) {
  if (id in timers) {
    var ticks = timers[id].endAt - (+new Date());
    if (ticks < config.mouseOutWaitMS)
      ticks = config.mouseOutWaitMS;
    timers[id].timerId = setTimeout( function() {
      HandleTimeout(id);
    }, ticks);
  }
}

function HandleInsertTimeout(id, duration) {
  if (!(id in timers)) {
    var endTicks = (+new Date()) + duration;
    timers[id]= { timerId:0, endAt:endTicks };
    HandleResumeTimeout(id);
  }
}

function HandleRemoveTimeout(id) {
  if (id in timers) {
    HandleSuspendTimeout(id);
    delete timers[id];
  }
}

function HandleTimeout(id) {
  if (id in timers) {
    timers[id].timerId = 0;
    HandleClose(id, false);
  }
}

function CreateDOMElement(tag, props) {
  var element = document.createElement(tag);
  for (var prop in props) {
    element[prop] = props[prop];
  }
  return element;
}

function CreateMsgElemForId(id) {
  return CreateDOMElement('div', {
    "id": id,
    "className": "msg",
    "onclick": function() {
      appNotification.clicked(id);
    },
    "onmouseover": function() {
      HandleSuspendTimeout(id)
    },
    "onmouseout": function() { 
      HandleResumeTimeout(id);
    }
  });
}

function CreateCloseElemForId(id) {
  return CreateDOMElement('a', {
    "href": "#",
    "title": "Close",
    "className": "close",
    "onclick": function(e) {
      e.stopPropagation();
      HandleClose(id, true);
      return false;
    }
  });
}

function ShowNotification(id, url) {
  console.debug("frame src: " + url);

  var div = CreateMsgElemForId(id);
  var frame = CreateDOMElement('iframe', {
    "src": url
  });

  if (config.width && config.height) {
    // 6 = border-left + border-right of the div.
    frame.style.width = (config.width - 6) + "px";
    frame.style.height = config.height + "px";
  }

  var img = CreateCloseElemForId(id);

  div.appendChild(frame);
  div.appendChild(img);
  document.body.appendChild(div);
  HandleInsertTimeout(id, config.displayMS);
  appNotification.displayed(id);
  HandleResize();
}
