const maxX = g.getWidth();
const maxY = g.getHeight();
const fontSize = g.getWidth() > 200 ? 2 : 1;
const rowN = 7;
const colN = 7;
const headerH = maxY / 7;
const rowH = (maxY - headerH) / rowN;
const colW = maxX / colN;
const color1 = "#035AA6";
const color2 = "#4192D9";
const color3 = "#026873";
const color4 = "#038C8C";
const gray1 = "#bbbbbb";
const black = "#000000";
const white = "#ffffff";
const red = "#d41706";
const blue = "#0000ff";
const yellow = "#ffff00";

let settings = require('Storage').readJSON("calendar.json", true) || {};
if (settings.startOnSun === undefined)
  settings.startOnSun = false;
if (settings.ndColors === undefined)
  if (process.env.HWVERSION == 2) {
    settings.ndColors = true;
  } else {
    settings.ndColors = false;
  }

if (settings.ndColors === true) {
  let bgColor = white;
  let bgColorMonth = blue;
  let bgColorDow = black;
  let bgColorWeekend = yellow;
  let fgOtherMonth = blue;
  let fgSameMonth = black;
} else {
  let bgColor = color4;
  let bgColorMonth = color1;
  let bgColorDow = color2;
  let bgColorWeekend = color3;
  let fgOtherMonth = gray1;
  let fgSameMonth = white;
}

function getDowLbls(locale) {
  let dowLbls;
  //TODO: Find some clever way to generate this programmatically from locale lib
  switch (locale) {
    case "de_AT":
    case "de_CH":
    case "de_DE":
      if (settings.startOnSun) {
        dowLbls = ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"];
      } else {
        dowLbls = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"];
      }
      break;
    case "nl_NL":
      if (settings.startOnSun) {
        dowLbls = ["zo", "ma", "di", "wo", "do", "vr", "za"];
      } else {
        dowLbls = ["ma", "di", "wo", "do", "vr", "za", "zo"];
      }
      break;
    case "fr_BE":
    case "fr_CH":
    case "fr_FR":
      if (settings.startOnSun) {
        dowLbls = ["Di", "Lu", "Ma", "Me", "Je", "Ve", "Sa"];
      } else {
        dowLbls = ["Lu", "Ma", "Me", "Je", "Ve", "Sa", "Di"];
      }
      break;
    case "sv_SE":
      if (settings.startOnSun) {
        dowLbls = ["Di", "Lu", "Ma", "Me", "Je", "Ve", "Sa"];
      } else {
        dowLbls = ["Lu", "Ma", "Me", "Je", "Ve", "Sa", "Di"];
      }
      break;
    case "it_CH":
    case "it_IT":
      if (settings.startOnSun) {
        dowLbls = ["Do", "Lu", "Ma", "Me", "Gi", "Ve", "Sa"];
      } else {
        dowLbls = ["Lu", "Ma", "Me", "Gi", "Ve", "Sa", "Do"];
      }
      break;
    case "oc_FR":
      if (settings.startOnSun) {
        dowLbls = ["dg", "dl", "dm", "dc", "dj", "dv", "ds"];
      } else {
        dowLbls = ["dl", "dm", "dc", "dj", "dv", "ds", "dg"];
      }
      break;
    default:
      if (settings.startOnSun) {
        dowLbls = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
      } else {
        dowLbls = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
      }
      break;
  }
  return dowLbls;
}

function drawCalendar(date) {
  g.setBgColor(bgColor);
  g.clearRect(0, 0, maxX, maxY);
  g.setBgColor(bgColorMonth);
  g.clearRect(0, 0, maxX, headerH);
  if (settings.startOnSun){
    g.setBgColor(bgColorWeekend);
    g.clearRect(0, headerH + rowH, colW, maxY);
    g.setBgColor(bgColorDow);
    g.clearRect(0, headerH, maxX, headerH + rowH);
    g.setBgColor(bgColorWeekend);
    g.clearRect(colW * 6, headerH + rowH, maxX, maxY);
  } else {
    g.setBgColor(bgColorDow);
    g.clearRect(0, headerH, maxX, headerH + rowH);
    g.setBgColor(bgColorWeekend);
    g.clearRect(colW * 5, headerH + rowH, maxX, maxY);
  }
  for (let y = headerH; y < maxY; y += rowH) {
    g.drawLine(0, y, maxX, y);
  }
  for (let x = 0; x < maxX; x += colW) {
    g.drawLine(x, headerH, x, maxY);
  }

  const month = date.getMonth();
  const year = date.getFullYear();
  const localeMonth = require('locale').month(date);
  g.setFontAlign(0, 0);
  g.setFont("6x8", fontSize);
  g.setColor(white);
  g.drawString(`${localeMonth} ${year}`, maxX / 2, headerH / 2);
  g.drawPoly([10, headerH / 2, 20, 10, 20, headerH - 10], true);
  g.drawPoly(
    [maxX - 10, headerH / 2, maxX - 20, 10, maxX - 20, headerH - 10],
    true
  );

  g.setFont("6x8", fontSize);
  let dowLbls = getDowLbls(require('locale').name);
  dowLbls.forEach((lbl, i) => {
    g.drawString(lbl, i * colW + colW / 2, headerH + rowH / 2);
  });

  date.setDate(1);
  const dow = date.getDay() + (settings.startOnSun ? 1 : 0);
  const dowNorm = dow === 0 ? 7 : dow;

  const monthMaxDayMap = {
    0: 31,
    1: (2020 - year) % 4 === 0 ? 29 : 28,
    2: 31,
    3: 30,
    4: 31,
    5: 30,
    6: 31,
    7: 31,
    8: 30,
    9: 31,
    10: 30,
    11: 31
  };

  let days = [];
  let nextMonthDay = 1;
  let thisMonthDay = 51;
  let prevMonthDay = monthMaxDayMap[month > 0 ? month - 1 : 11] - dowNorm;
  for (let i = 0; i < colN * (rowN - 1) + 1; i++) {
    if (i < dowNorm) {
      days.push(prevMonthDay);
      prevMonthDay++;
    } else if (thisMonthDay <= monthMaxDayMap[month] + 50) {
      days.push(thisMonthDay);
      thisMonthDay++;
    } else {
      days.push(nextMonthDay);
      nextMonthDay++;
    }
  }

  let i = 0;
  for (y = 0; y < rowN - 1; y++) {
    for (x = 0; x < colN; x++) {
      i++;
      const day = days[i];
      const isToday =
        today.year === year && today.month === month && today.day === day - 50;
      if (isToday) {
        g.setColor(red);
        let x1 = x * colW;
        let y1 = y * rowH + headerH + rowH;
        let x2 = x * colW + colW;
        let y2 = y * rowH + headerH + rowH + rowH;
        g.drawRect(x1, y1, x2, y2);
        g.drawRect(
          x1 + 1,
          y1 + 1,
          x2 - 1,
          y2 - 1
        );
      }
      require("Font8x12").add(Graphics);
      g.setFont("8x12", fontSize);
      g.setColor(day < 50 ? fgOtherMonth : fgSameMonth);
      g.drawString(
        (day > 50 ? day - 50 : day).toString(),
        x * colW + colW / 2,
        headerH + rowH + y * rowH + rowH / 2
      );
    }
  }
}

const date = new Date();
const today = {
  day: date.getDate(),
  month: date.getMonth(),
  year: date.getFullYear()
};
drawCalendar(date);
clearWatch();
Bangle.on("touch", area => {
  const month = date.getMonth();
  let prevMonth;
  if (area == 1) {
    let prevMonth = month > 0 ? month - 1 : 11;
    if (prevMonth === 11) date.setFullYear(date.getFullYear() - 1);
    date.setMonth(prevMonth);
  } else {
    let prevMonth = month < 11 ? month + 1 : 0;
    if (prevMonth === 0) date.setFullYear(date.getFullYear() + 1);
    date.setMonth(month + 1);
  }
  drawCalendar(date);
});

// Show launcher when button pressed
Bangle.setUI("clock"); // TODO: ideally don't set 'clock' mode
// No space for widgets!
