diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..dc7ffb1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+developer_key
+bin/**
+output/**
+venu2plus/**
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..5279e9e
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,22 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "monkeyc",
+ "request": "launch",
+ "name": "Run App",
+ "stopAtLaunch": false,
+ "device": "${command:GetTargetDevice}"
+ },
+ {
+ "type": "monkeyc",
+ "request": "launch",
+ "name": "Run Tests",
+ "runTests": true,
+ "device": "${command:GetTargetDevice}"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/instinct/test2.prg b/instinct/test2.prg
new file mode 100644
index 0000000..7ad2cb0
Binary files /dev/null and b/instinct/test2.prg differ
diff --git a/instinct/test2.prg.debug.xml b/instinct/test2.prg.debug.xml
new file mode 100644
index 0000000..5ed9a50
--- /dev/null
+++ b/instinct/test2.prg.debug.xml
@@ -0,0 +1,855 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/manifest.xml b/manifest.xml
new file mode 100644
index 0000000..020292c
--- /dev/null
+++ b/manifest.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/monkey.jungle b/monkey.jungle
new file mode 100644
index 0000000..b2200b1
--- /dev/null
+++ b/monkey.jungle
@@ -0,0 +1 @@
+project.manifest = manifest.xml
diff --git a/resources/drawables/drawables.xml b/resources/drawables/drawables.xml
new file mode 100644
index 0000000..877e9aa
--- /dev/null
+++ b/resources/drawables/drawables.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/resources/drawables/launcher_icon.png b/resources/drawables/launcher_icon.png
new file mode 100644
index 0000000..d3594e7
Binary files /dev/null and b/resources/drawables/launcher_icon.png differ
diff --git a/resources/layouts/layout.xml b/resources/layouts/layout.xml
new file mode 100644
index 0000000..492d039
--- /dev/null
+++ b/resources/layouts/layout.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/resources/strings/strings.xml b/resources/strings/strings.xml
new file mode 100644
index 0000000..f290f81
--- /dev/null
+++ b/resources/strings/strings.xml
@@ -0,0 +1,3 @@
+
+ test2
+
diff --git a/source/coordinate.mc b/source/coordinate.mc
new file mode 100644
index 0000000..383faee
--- /dev/null
+++ b/source/coordinate.mc
@@ -0,0 +1,180 @@
+import Toybox.Graphics;
+
+class Coordinate
+{
+ public var X;
+ public var Y;
+
+ public var W;
+
+ function initialize(x, y)
+ {
+ X = x;
+ Y = y;
+ }
+
+ function drawLargeTextAt(dc, text)
+ {
+ dc.drawText(
+ X, // gets the width of the device and divides by 2
+ Y, // gets the height of the device and divides by 2
+ Graphics.FONT_NUMBER_THAI_HOT, // sets the font size
+ text, // the String to display
+ Graphics.TEXT_JUSTIFY_CENTER // sets the justification for the text
+ );
+ }
+
+ function drawSmallTextAt(dc, text)
+ {
+ dc.drawText(
+ X, // gets the width of the device and divides by 2
+ Y, // gets the height of the device and divides by 2
+ 2, // sets the font size
+ text, // the String to display
+ Graphics.TEXT_JUSTIFY_CENTER // sets the justification for the text
+ );
+ }
+
+ function drawTinyTextAt(dc, text)
+ {
+ dc.drawText(
+ X, // gets the width of the device and divides by 2
+ Y, // gets the height of the device and divides by 2
+ 0, // sets the font size
+ text, // the String to display
+ Graphics.TEXT_JUSTIFY_CENTER // sets the justification for the text
+ );
+ }
+
+ function drawHorizontalLine(dc, width, length)
+ {
+ dc.setPenWidth(width);
+ dc.drawLine(X, Y, X + length, Y);
+ }
+
+ function drawVerticalLine(dc, width, length)
+ {
+ dc.setPenWidth(width);
+ dc.drawLine(X, Y, X, Y + length);
+ }
+
+ function drawPercentageCurvedBarChart(dc, height as Double, width as Double, data as PlottableArray)
+ {
+ if(data.size() <= 0){return;}
+
+ var min = 0;
+ var max = 100;
+
+ // degrees start from 180 and go to 360
+ var r = 24;
+ var rLen = 180;
+ var interval = rLen / (data.data.size() - 1);
+ var leftAngle = 180;
+
+ dc.setPenWidth(1);
+ // dc.drawLine(X - 4, Y, X - 4, Y + height);
+ // dc.drawLine(X - 4, Y, X - 2 + width, Y);
+
+ dc.drawArc(X, Y, r, 0, leftAngle, leftAngle + rLen);
+
+ dc.setPenWidth(1);
+
+ var bottomY = Y + height;
+ var onePercent = r / (max - min);
+
+ for (var i = 0; i < data.size(); ++i)
+ {
+ var item = data.data[i];
+ var itemScale = 1 - (item/100.0);
+
+ var angle = Math.toRadians(leftAngle + (i * interval));
+ var x_for_i = X - r * Math.cos(angle);
+ var y_for_i = Y - r * Math.sin(angle);
+
+ var topX = X + ((x_for_i - X) * itemScale);
+ var topY = Y + ((y_for_i - Y) * itemScale);
+
+ dc.drawLine(x_for_i, y_for_i, topX, topY);
+ }
+ }
+
+ function drawPercentageBarChart(dc, height as Double, width as Double, data as PlottableArray)
+ {
+ if(data.data.size() <= 0){return;}
+
+ var min = 0;
+ var max = 100;
+
+ dc.setPenWidth(1);
+ dc.drawLine(X - 4, Y, X - 4, Y + height);
+ dc.drawLine(X - 4, Y, X - 2 + width, Y);
+
+ dc.setPenWidth(2);
+
+ var bottomY = Y + height;
+
+ var interval = width / data.data.size();
+ var onePercent = height / (max - min);
+
+ for (var i = 0; i < data.data.size(); ++i)
+ {
+ var item = data.data[i];
+ var itemHeight = onePercent * item;
+
+ var leftShift = interval * i;
+
+ dc.drawLine(X + leftShift, bottomY, X + leftShift, bottomY - itemHeight);
+ }
+ }
+
+ function drawArray(dc, height as Double, data as PlottableArray, minOverride, maxOverride)
+ {
+ var max = data.max > maxOverride ? data.max : maxOverride;
+ var min = data.min < minOverride ? data.min : minOverride;
+ var diff = (max - min);
+ var oneHR = height / diff;
+
+ dc.setPenWidth(1);
+
+ var eightyP = Y + ((max - 80) * oneHR);
+ dc.drawLine(X - 1, eightyP, X + 2, eightyP);
+
+ var oneTwentyP = Y + ((max - 110) * oneHR);
+ dc.drawLine(X - 1, oneTwentyP, X + 2, oneTwentyP);
+
+ dc.drawLine(X - 1, oneTwentyP, X - 1, eightyP);
+
+ dc.setPenWidth(2);
+
+ var prevX = -1;
+ var prevY = -1;
+
+ var dX = X + 5;
+
+ for (var i = 0; i < data.data.size() && i + dX <= 156; ++i)
+ {
+ var item = data.data[i];
+
+ if(item == data.INVALID)
+ {
+ continue;
+ }
+
+ var hrDiffFromMax = max - item;
+
+ var currentHR = oneHR * hrDiffFromMax;
+
+ if(prevX == -1)
+ {
+ prevX = dX + i;
+ prevY = Y + currentHR;
+ dc.drawPoint(dX + i, Y + currentHR);
+ continue;
+ }
+
+ dc.drawLine(prevX, prevY, dX + i, Y + currentHR);
+ prevX = dX + i;
+ prevY = Y + currentHR;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/forecast.mc b/source/forecast.mc
new file mode 100644
index 0000000..66f9e28
--- /dev/null
+++ b/source/forecast.mc
@@ -0,0 +1,83 @@
+class ForecastResult
+{
+ function initialize(data, rain)
+ {
+ Data = data;
+ Rain = rain;
+ }
+
+ public var Data;
+ public var Rain;
+}
+
+class Forecast
+{
+ using Toybox.Time;
+ using Toybox.Time.Gregorian;
+
+ private static var cacheExpiry;
+ private static var cacheValue;
+
+ private static var HALF_HOUR;
+
+ function initialize()
+ {
+ HALF_HOUR = new Time.Duration(1800);
+ }
+
+ function getNextEvent(current)
+ {
+ var moment = Time.now();
+
+ if(cacheExpiry == null || cacheExpiry.compare(moment) < 0)
+ {
+ if(current != null)
+ {
+ var forecast = Toybox.Weather.getHourlyForecast();
+ if(forecast != null)
+ {
+ var currPrecip = current.precipitationChance;
+ var graphData = new PlottableArray(-1000);
+ var rain = false;
+
+ for (var i = 0; i < forecast.size(); ++i)
+ {
+ graphData.add(forecast[i].precipitationChance);
+
+ if(i < 6 && forecast[i].precipitationChance >= 50) //&& forecast[i].precipitationChance > currPrecip
+ {
+ rain = true;
+ // var rainTime = Toybox.Time.Gregorian.info(forecast[i].forecastTime, Time.FORMAT_MEDIUM);
+ // saliencyAreaLineOneCoor.drawSmallTextAt(dc, "rain @");
+ // saliencyAreaLineTwoCoor.drawSmallTextAt(dc, Lang.format("$1$:$2$", [rainTime.hour, rainTime.min.format("%02d")]));
+ // return;
+ }
+
+ if(i > 5 && rain == false)
+ {
+ break;
+ }
+ }
+
+ if(rain)
+ {
+ cacheExpiry = moment.add(HALF_HOUR);
+ cacheValue = new ForecastResult(graphData, true);
+ // saliencyAreaGraphCoor.drawPercentageBarChart(dc, 25.0 /*height*/, 40.0, graphData);
+ return cacheValue;
+ }else
+ {
+ cacheExpiry = moment.add(HALF_HOUR);
+ cacheValue = new ForecastResult(graphData, false);
+ return cacheValue;
+ }
+ }
+
+ return new ForecastResult(null, false);
+ }
+ return cacheValue;
+ }else{
+ return cacheValue;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/heartRate.mc b/source/heartRate.mc
new file mode 100644
index 0000000..414fdba
--- /dev/null
+++ b/source/heartRate.mc
@@ -0,0 +1,60 @@
+import Toybox.Activity;
+import Toybox.ActivityMonitor;
+
+class HeartRate
+{
+ private var _showHeartRate;
+ private var graphData;
+ // private static var sixHours = new Time.Duration(12600);
+ // private static var oneMin = new Time.Duration(600);
+
+ public function initialize(showHeartRate)
+ {
+ _showHeartRate = showHeartRate;
+ }
+
+ function currentHeartRate()
+ {
+ var info = Activity.getActivityInfo();
+
+ if(info == null || info.currentHeartRate == null)
+ {
+ return "--";
+ }
+
+ return info.currentHeartRate;
+ }
+
+ function heartRateHistory(){
+ graphData = new PlottableArray(ActivityMonitor.INVALID_HR_SAMPLE);
+
+ if (ActivityMonitor has :getHeartRateHistory) {
+ var getNext = true;
+
+ var iterator = ActivityMonitor.getHeartRateHistory(100, true /* newestFirst */);
+
+ while (getNext) {
+ var sample = iterator.next();
+ if (sample != null) {
+
+
+ if (sample.heartRate == ActivityMonitor.INVALID_HR_SAMPLE)
+ {
+ graphData.addInvalidData(sample.heartRate);
+ }
+ else
+ {
+ graphData.add(sample.heartRate);
+ }
+ }
+ else
+ {
+ getNext = false;
+ }
+ }
+ }
+
+ return graphData;
+ }
+}
+
diff --git a/source/plottableArray.mc b/source/plottableArray.mc
new file mode 100644
index 0000000..28d287c
--- /dev/null
+++ b/source/plottableArray.mc
@@ -0,0 +1,49 @@
+using Toybox.Time;
+
+class PlottableArray
+{
+ public var min;
+ public var max;
+
+ public var data;
+
+ public var capacity;
+
+ public var INVALID;
+
+ function initialize(invalidData, capacity)
+ {
+ min = 2000;
+ max = -1;
+ data = [];
+ capacity = capacity;
+
+ INVALID = invalidData;
+ }
+
+ function addInvalidData(item as Numeric)
+ {
+ data.add(item);
+ }
+
+ function add(item as Numeric, when as Time.Moment)
+ {
+ if(when != null && data.size() == capacity)
+ {
+
+ }
+
+ if(min > item)
+ {
+ min = item;
+ }
+
+ if(max < item)
+ {
+ max = item;
+ }
+
+ data.add(item);
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/source/sunRiseSet.mc b/source/sunRiseSet.mc
new file mode 100644
index 0000000..1b1bc87
--- /dev/null
+++ b/source/sunRiseSet.mc
@@ -0,0 +1,58 @@
+class SunRiseSetResult
+{
+ function initialize(type, timeText, time)
+ {
+ Type = type;
+ TimeText = timeText;
+ Time = time;
+ }
+
+ public var Type;
+ public var TimeText;
+ public var Time;
+}
+
+class SunRiseSet
+{
+ using Toybox.Time;
+ using Toybox.Time.Gregorian;
+
+ private static var cacheExpiry;
+ private static var cacheValue;
+
+ function initialize()
+ {
+
+ }
+
+ function getNextEvent(current)
+ {
+ var moment = Time.now();
+
+ if(cacheExpiry == null || cacheExpiry.compare(moment) < 0)
+ {
+ if(current.observationLocationPosition == null)
+ {
+ return new SunRiseSetResult("--", Lang.format("$1$:$2$", ["--", "--"]));
+ }
+
+ var currSunset = Toybox.Weather.getSunset(current.observationLocationPosition, moment);
+
+ if(currSunset.compare(moment) > 0)
+ {
+ var set = Gregorian.info(currSunset, Time.FORMAT_MEDIUM);
+ cacheValue = new SunRiseSetResult("set", Lang.format("$1$:$2$", [set.hour, set.min.format("%02d")]), currSunset);
+ cacheExpiry = currSunset;
+ return cacheValue;
+ }
+
+ var nextSunRise = Toybox.Weather.getSunrise(current.observationLocationPosition, moment.add(new Time.Duration(Gregorian.SECONDS_PER_DAY)));
+ var rise = Gregorian.info(nextSunRise, Time.FORMAT_MEDIUM);
+ cacheValue = new SunRiseSetResult("rise", Lang.format("$1$:$2$", [rise.hour, rise.min.format("%02d")]), nextSunRise);
+ cacheExpiry = nextSunRise;
+ return cacheValue;
+ }else{
+ return cacheValue;
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/test2App.mc b/source/test2App.mc
new file mode 100644
index 0000000..4384331
--- /dev/null
+++ b/source/test2App.mc
@@ -0,0 +1,28 @@
+import Toybox.Application;
+import Toybox.Lang;
+import Toybox.WatchUi;
+
+class test2App extends Application.AppBase {
+
+ function initialize() {
+ AppBase.initialize();
+ }
+
+ // onStart() is called on application start up
+ function onStart(state as Dictionary?) as Void {
+ }
+
+ // onStop() is called when your application is exiting
+ function onStop(state as Dictionary?) as Void {
+ }
+
+ // Return the initial view of your application here
+ function getInitialView() as Array? {
+ return [ new test2View() ] as Array;
+ }
+
+}
+
+function getApp() as test2App {
+ return Application.getApp() as test2App;
+}
\ No newline at end of file
diff --git a/source/test2View.mc b/source/test2View.mc
new file mode 100644
index 0000000..5922736
--- /dev/null
+++ b/source/test2View.mc
@@ -0,0 +1,242 @@
+import Toybox.Graphics;
+import Toybox.Lang;
+import Toybox.System;
+import Toybox.WatchUi;
+import Toybox.Activity;
+import Toybox.Weather;
+import Toybox.UserProfile;
+
+class test2View extends WatchUi.WatchFace {
+
+ private var sleep = false;
+
+ // private var dayCoordinate = new Coordinate(14, 8);
+ // private var dayOfWeekCoordinate = new Coordinate(2, 22);
+ // private var monthCoordinate = new Coordinate(2, 45);
+
+ private var hr = new HeartRate(true);
+ private var sunRiseSet = new SunRiseSet();
+ private var forecast = new Forecast();
+
+ private var utcClockCoordinate = new Coordinate(57, -1);
+ private var japanClockCoordinate = new Coordinate(30, -1);
+ private var turkeyClockCoordinate = new Coordinate(85, -1);
+ private var topDividerStart = new Coordinate(17, 22);
+
+ private var clockCoordinate = new Coordinate(50, 35);
+ private var secondsCoordinate = new Coordinate(115, 70);
+
+ private var middleBarStartY = 98;
+
+ private var bottomDividerStart = new Coordinate(5, middleBarStartY + 20);
+ private var bottomVerticalDividerOneStart = new Coordinate(50, middleBarStartY);
+ private var bottomVerticalDividerTwoStart = new Coordinate(100, middleBarStartY);
+
+ private var currentTemperatureCoor = new Coordinate(28, middleBarStartY);
+ private var currentTemperatureFCoor = new Coordinate(30, middleBarStartY);
+
+ private var stepsCoor = new Coordinate(75, middleBarStartY);
+ private var bottomRightBoxCoor = new Coordinate(127, middleBarStartY);
+
+ private var heartRateAreaY = 122;
+
+ private var heartRateCoordinate = new Coordinate(25, heartRateAreaY);
+ private var heartRateTrendlineCoordinate = new Coordinate(40, heartRateAreaY);
+
+ private var saliencyAreaLineOneCoor = new Coordinate(135, 5);
+ private var saliencyAreaLineTwoCoor = new Coordinate(135, 25);
+
+ private var saliencyAreaGraphCoor = new Coordinate(118, 14);
+
+ private var saliencyAreaCircleGraphCoor = new Coordinate(136, 27);
+
+ private var prevMin;
+
+ private var userProfile;
+
+ function initialize() {
+ WatchFace.initialize();
+ }
+
+ // Load your resources here
+ function onLayout(dc as Dc) as Void {
+ setLayout(Rez.Layouts.WatchFace(dc));
+ }
+
+ // Called when this View is brought to the foreground. Restore
+ // the state of this View and prepare it to be shown. This includes
+ // loading resources into memory.
+ function onShow() as Void {
+ }
+
+ // Seems like we need to update minutes here only
+ function onPartialUpdate(dc as Dc)
+ {
+ // // dc.setClip(clockCoordinate.X, clockCoordinate.Y, 20, 25);
+ // // dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_WHITE);
+
+ // // drawClocks(dc, true);
+ }
+
+ // Update the view
+ function onUpdate(dc as Dc) as Void {
+
+ // userProfile = Toybox.UserProfile.getProfile();
+
+ var time = System.getClockTime();
+ // var currHour = time.hour;
+ var currMin = time.min;
+
+ if(currMin == prevMin)
+ {
+ dc.setClip(heartRateCoordinate.X - 20, heartRateCoordinate.Y, 34, 30);
+ dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_WHITE);
+ dc.clear();
+
+ var currentHeartRate = hr.currentHeartRate();
+ var heartrateString = Lang.format("$1$", [currentHeartRate]);
+ heartRateCoordinate.drawSmallTextAt(dc, heartrateString);
+
+ return;
+ }
+
+ dc.setClip(0, 0, 170, 170);
+ dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_WHITE);
+ dc.clear();
+
+ drawClocks(dc);
+ drawSaliencyArea(dc);
+
+ var hrData = hr.heartRateHistory();
+ heartRateTrendlineCoordinate.drawArray(dc, 30.0, hrData, 100, 120);
+
+ var currentHeartRate = hr.currentHeartRate();
+ var heartrateString = Lang.format("$1$", [currentHeartRate]);
+ heartRateCoordinate.drawSmallTextAt(dc, heartrateString);
+
+ var current = Toybox.Weather.getCurrentConditions();
+ if(current != null && current.feelsLikeTemperature != null)
+ {
+ var fah = (current.feelsLikeTemperature * 1.8 + 32).toNumber();
+ // currentTemperatureFCoor.drawTinyTextAt(dc, Lang.format("$1$", [fah]));
+ currentTemperatureCoor.drawSmallTextAt(dc, Lang.format("$1$°$2$", [fah, WeatherConditions.GetWeatherEmoji(current.condition)]));
+ }else
+ {
+ currentTemperatureCoor.drawSmallTextAt(dc, "--");
+ }
+ // currentTemperatureCoor.drawSmallTextAt(dc, Lang.format("$1$ $2$", [current.feelsLikeTemperature, WeatherConditions.GetWeatherEmoji(current.condition)]));
+
+ var info = ActivityMonitor.getInfo();
+ if(info != null)
+ {
+ var steps = info.steps;
+ stepsCoor.drawSmallTextAt(dc, Lang.format("$1$", [steps]));
+ }
+
+ topDividerStart.drawHorizontalLine(dc, 1, 78);
+ bottomDividerStart.drawHorizontalLine(dc, 1, 145);
+ bottomVerticalDividerOneStart.drawVerticalLine(dc, 1, 20);
+ bottomVerticalDividerTwoStart.drawVerticalLine(dc, 1, 20);
+
+ prevMin = System.getClockTime().min;
+ }
+
+ function drawClocks(dc as Dc)
+ {
+ var clockTime = System.getClockTime();
+ var timeString = Lang.format("$1$:$2$", [clockTime.hour, clockTime.min.format("%02d")]);
+ clockCoordinate.drawLargeTextAt(dc, timeString);
+
+ var moment = Time.now();
+ var currentTime = Toybox.Time.Gregorian.info(moment, Time.FORMAT_MEDIUM);
+ // dayCoordinate.drawTinyTextAt(dc, Lang.format("$1$", [currentTime.day.format("%02d")]));
+ // dayOfWeekCoordinate.drawTinyTextAt(dc, Lang.format("$1$", [currentTime.day_of_week]));
+ // monthCoordinate.drawTinyTextAt(dc, Lang.format("$1$", [currentTime.month]));
+
+ bottomRightBoxCoor.drawSmallTextAt(dc, Lang.format("$1$ $2$", [currentTime.day_of_week, currentTime.day.format("%02d")]));
+
+ var utcTime = Toybox.Time.Gregorian.utcInfo(moment, Time.FORMAT_MEDIUM);
+ var utcTimeString = Lang.format("$1$", [utcTime.hour.format("%02d")]);
+
+ utcClockCoordinate.drawSmallTextAt(dc, utcTimeString);
+
+ var japanHour = (utcTime.hour + 9) %24;
+ var turkeyHour = (utcTime.hour + 3) %24;
+
+ japanClockCoordinate.drawSmallTextAt(dc, Lang.format("$1$", [japanHour.format("%02d")]));
+ turkeyClockCoordinate.drawSmallTextAt(dc, Lang.format("$1$", [turkeyHour.format("%02d")]));
+
+ // if(!sleep)
+ // {
+ // var secondsTimeString = Lang.format("$1$", [clockTime.sec.format("%02d")]);
+ // secondsCoordinate.drawSmallTextAt(dc, secondsTimeString);
+ // }else
+ // {
+ // var secondsTimeString = " ";
+ // secondsCoordinate.drawSmallTextAt(dc, secondsTimeString);
+ // }
+ }
+
+ function drawSaliencyArea(dc as Dc)
+ {
+ var stats = System.getSystemStats();
+ if(stats != null)
+ {
+ var pwr = stats.battery;
+ if(pwr < 10.1)
+ {
+ var batStr = Lang.format("$1$%", [ pwr.format( "%2d" ) ] );
+ saliencyAreaLineOneCoor.drawSmallTextAt(dc, "low");
+ saliencyAreaLineTwoCoor.drawSmallTextAt(dc, batStr);
+ return;
+ }
+ }
+
+ var current = Toybox.Weather.getCurrentConditions();
+ if(current != null && current.feelsLikeTemperature != null && current.feelsLikeTemperature <= 0)
+ {
+ saliencyAreaLineOneCoor.drawSmallTextAt(dc, "❄️");
+ saliencyAreaLineTwoCoor.drawSmallTextAt(dc, current.feelsLikeTemperature);
+
+ return;
+ }
+
+ if(current != null)
+ {
+ var forecastResult = forecast.getNextEvent(current);
+
+ if(forecastResult != null && forecastResult.Data != null && forecastResult.Rain) // if rain is false should be enough here but can't be too safe with this stuff
+ {
+ // saliencyAreaCircleGraphCoor.drawPercentageCurvedBarChart(dc, 25.0, 40.0, forecastResult.Data);
+
+ saliencyAreaGraphCoor.drawPercentageBarChart(dc, 25.0 /*height*/, 40.0, forecastResult.Data);
+ return;
+ }
+ }
+
+ if(current != null && current.observationLocationPosition != null)
+ {
+ var riseSetResult = sunRiseSet.getNextEvent(current);
+ saliencyAreaLineOneCoor.drawSmallTextAt(dc, riseSetResult.Type);
+ saliencyAreaLineTwoCoor.drawSmallTextAt(dc, riseSetResult.TimeText);
+ return;
+ }
+ }
+
+ // Called when this View is removed from the screen. Save the
+ // state of this View here. This includes freeing resources from
+ // memory.
+ function onHide() as Void {
+ }
+
+ // The user has just looked at their watch. Timers and animations may be started here.
+ function onExitSleep() as Void {
+ sleep = false;
+ }
+
+ // Terminate any active timers and prepare for slow updates.
+ function onEnterSleep() as Void {
+ sleep = true;
+ }
+
+}
diff --git a/source/weatherConditions.mc b/source/weatherConditions.mc
new file mode 100644
index 0000000..aa28fe8
--- /dev/null
+++ b/source/weatherConditions.mc
@@ -0,0 +1,48 @@
+class WeatherConditions
+{
+ static function GetWeatherEmoji(c as Number)
+ {
+
+ //https://developer.garmin.com/connect-iq/api-docs/Toybox/Weather.html#getCurrentConditions-instance_function
+ switch (c){
+ case 0: //CONDITION_CLEAR
+ case 22: //CONDITION_PARTLY_CLEAR
+ case 23: //CONDITION_MOSTLY_CLEAR
+ return "sn";
+ case 1: //CONDITION_PARTLY_CLOUDY
+ return "pc";
+ case 2: //CONDITION_MOSTLY_CLOUDY
+ case 20: //CONDITION_CLOUDY
+ return "cl";
+ case 3: //CONDITION_RAIN
+ case 14: //CONDITION_LIGHT_RAIN
+ case 15: //CONDITION_HEAVY_RAIN
+ case 45: //CONDITION_CLOUDY_CHANCE_OF_RAIN
+ case 25: //CONDITION_SHOWERS
+ case 26: //CONDITION_HEAVY_SHOWERS
+ case 27: //CONDITION_CHANCE_OF_SHOWERS
+ return "rn";
+ case 4: //CONDITION_SNOW
+ case 46: //CONDITION_CLOUDY_CHANCE_OF_SNOW
+ return "sw";
+ case 5: //CONDITION_WINDY
+ return "wd";
+ case 6: //CONDITION_THUNDERSTORMS
+ return "st";
+ case 7: //CONDITION_WINTRY_MIX
+ return "st";
+ case 8: //CONDITION_FOG
+ return "fg";
+ case 9: //CONDITION_HAZY
+ case 39: //CONDITION_HAZE
+ return "hz";
+ case 33: //CONDITION_SMOKE
+ return "smk";
+
+ default:
+ return "u";
+ }
+
+ return "p";
+ }
+}
\ No newline at end of file