diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5e56e04
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/bin
diff --git a/manifest.xml b/manifest.xml
new file mode 100644
index 0000000..8610910
--- /dev/null
+++ b/manifest.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+ eng
+
+
+
+
\ No newline at end of file
diff --git a/monkey.jungle b/monkey.jungle
new file mode 100755
index 0000000..87796c7
--- /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 100755
index 0000000..a22c33c
--- /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 100755
index 0000000..d3594e7
Binary files /dev/null and b/resources/drawables/launcher_icon.png differ
diff --git a/resources/layouts/layouts.xml b/resources/layouts/layouts.xml
new file mode 100755
index 0000000..b620a0a
--- /dev/null
+++ b/resources/layouts/layouts.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+ 64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/strings/strings.xml b/resources/strings/strings.xml
new file mode 100644
index 0000000..1e2c6f4
--- /dev/null
+++ b/resources/strings/strings.xml
@@ -0,0 +1,5 @@
+
+ RepaField
+
+ My Value
+
diff --git a/source/RepaFieldApp.mc b/source/RepaFieldApp.mc
new file mode 100644
index 0000000..df4bf1f
--- /dev/null
+++ b/source/RepaFieldApp.mc
@@ -0,0 +1,28 @@
+import Toybox.Application;
+import Toybox.Lang;
+import Toybox.WatchUi;
+
+class RepaFieldApp 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 RepaFieldView() ] as Array;
+ }
+
+}
+
+function getApp() as RepaFieldApp {
+ return Application.getApp() as RepaFieldApp;
+}
\ No newline at end of file
diff --git a/source/RepaFieldBackground.mc b/source/RepaFieldBackground.mc
new file mode 100644
index 0000000..5007272
--- /dev/null
+++ b/source/RepaFieldBackground.mc
@@ -0,0 +1,28 @@
+import Toybox.Application;
+import Toybox.Graphics;
+import Toybox.WatchUi;
+
+class Background extends WatchUi.Drawable {
+
+ hidden var mColor as ColorValue;
+
+ function initialize() {
+ var dictionary = {
+ :identifier => "Background"
+ };
+
+ Drawable.initialize(dictionary);
+
+ mColor = Graphics.COLOR_BLACK;
+ }
+
+ function setColor(color as ColorValue) as Void {
+ mColor = color;
+ }
+
+ function draw(dc as Dc) as Void {
+ dc.setColor(Graphics.COLOR_TRANSPARENT, mColor);
+ dc.clear();
+ }
+
+}
diff --git a/source/RepaFieldHeartRate.mc b/source/RepaFieldHeartRate.mc
new file mode 100644
index 0000000..6385cdc
--- /dev/null
+++ b/source/RepaFieldHeartRate.mc
@@ -0,0 +1,56 @@
+import Toybox.Application;
+import Toybox.Graphics;
+import Toybox.WatchUi;
+import Toybox.Lang;
+import Toybox.System;
+
+class HeartRate extends WatchUi.Drawable {
+
+ hidden var hrZones as Array;
+ hidden var hrValue as Numeric;
+ hidden var aColor as Graphics.ColorValue | Number;
+ hidden var y as Numeric;
+
+ function initialize(params as Dictionary) {
+ Drawable.initialize(params);
+
+ hrZones = [100, 120, 140, 160, 180, 200];
+ hrValue = 0.0f;
+ aColor = 0xFF8800;
+ y = 64;
+ if (params.hasKey(:y)) {
+ y = params.get(:y) as Number;
+ }
+ }
+
+ function setHRZones(zones as Array) as Void {
+ hrZones = zones;
+ }
+
+ function setHRValue(value as Numeric) as Void {
+ hrValue = value;
+ }
+
+ function setHRColor(color) as Void {
+ aColor = color;
+ }
+
+ function draw(dc as Dc) as Void {
+ dc.setPenWidth(8);
+ dc.setColor(0x555555, Graphics.COLOR_TRANSPARENT);
+ var width = dc.getWidth();
+ dc.drawLine(width * .1, 64, width * .9, 64);
+
+ var percentage = 0.0f;
+ var zoneNr = hrZones.size();
+ if (hrValue > hrZones[zoneNr - 1]) {
+ percentage = 1.0f;
+ } else if (hrValue < hrZones[0]) {
+ percentage = .0f;
+ } else {
+ percentage = (hrValue - hrZones[0]).toFloat() / (hrZones[zoneNr - 1] - hrZones[0]);
+ }
+ dc.setColor(aColor, Graphics.COLOR_TRANSPARENT);
+ dc.drawLine(width * .1, 64, width * (.1 + .8 * percentage), 64);
+ }
+}
diff --git a/source/RepaFieldStamina.mc b/source/RepaFieldStamina.mc
new file mode 100644
index 0000000..6fab78a
--- /dev/null
+++ b/source/RepaFieldStamina.mc
@@ -0,0 +1,18 @@
+import Toybox.Application;
+import Toybox.Graphics;
+import Toybox.WatchUi;
+
+class Stamina extends WatchUi.Drawable {
+
+ function initialize() {
+ var dictionary = {
+ :identifier => "Stamina"
+ };
+
+ Drawable.initialize(dictionary);
+ }
+
+ function draw(dc as Dc) as Void {
+ dc.setColor(0xFF8800, Graphics.COLOR_TRANSPARENT);
+ }
+}
diff --git a/source/RepaFieldTrack.mc b/source/RepaFieldTrack.mc
new file mode 100644
index 0000000..3ab8e20
--- /dev/null
+++ b/source/RepaFieldTrack.mc
@@ -0,0 +1,18 @@
+import Toybox.Application;
+import Toybox.Graphics;
+import Toybox.WatchUi;
+
+class Track extends WatchUi.Drawable {
+
+ function initialize() {
+ var dictionary = {
+ :identifier => "Track"
+ };
+
+ Drawable.initialize(dictionary);
+ }
+
+ function draw(dc as Dc) as Void {
+ dc.setColor(0xFF8800, Graphics.COLOR_TRANSPARENT);
+ }
+}
diff --git a/source/RepaFieldView.mc b/source/RepaFieldView.mc
new file mode 100644
index 0000000..84e4c9f
--- /dev/null
+++ b/source/RepaFieldView.mc
@@ -0,0 +1,131 @@
+import Toybox.Activity;
+import Toybox.Graphics;
+import Toybox.Lang;
+import Toybox.UserProfile;
+import Toybox.WatchUi;
+
+class RepaFieldView extends WatchUi.DataField {
+
+ hidden var hrValue as Numeric;
+ hidden var ahrValue as Numeric;
+ hidden var mhrValue as Numeric;
+ hidden var hrZones as Array;
+
+ function initialize() {
+ DataField.initialize();
+ hrValue = 0;
+ ahrValue = 0;
+ mhrValue = 0;
+ hrZones = UserProfile.getHeartRateZones(UserProfile.getCurrentSport());
+ }
+
+ function calculateHRColor(hr as Numeric) as Numeric {
+ var hrColor = Graphics.COLOR_BLACK;
+ if (hrZones != null) {
+ if (hr < hrZones[1]) {
+ hrColor = Graphics.COLOR_LT_GRAY;
+ } else if (hr < hrZones[2]) {
+ hrColor = Graphics.COLOR_BLUE;
+ } else if (hr < hrZones[3]) {
+ hrColor = Graphics.COLOR_GREEN;
+ } else if (hr < hrZones[4]) {
+ hrColor = Graphics.COLOR_YELLOW;
+ } else if (hr < hrZones[5]) {
+ hrColor = Graphics.COLOR_ORANGE;
+ } else {
+ hrColor = Graphics.COLOR_RED;
+ }
+ }
+ return hrColor;
+ }
+
+ // Set your layout here. Anytime the size of obscurity of
+ // the draw context is changed this will be called.
+ function onLayout(dc as Dc) as Void {
+ var obscurityFlags = DataField.getObscurityFlags();
+
+ // TODO ?
+ // Top layout
+ if (obscurityFlags == (OBSCURE_TOP | OBSCURE_LEFT | OBSCURE_RIGHT)) {
+ View.setLayout(Rez.Layouts.TopLayout(dc));
+
+ // Bottom layout
+ } else if (obscurityFlags == (OBSCURE_BOTTOM | OBSCURE_LEFT | OBSCURE_RIGHT)) {
+ View.setLayout(Rez.Layouts.BottomLayout(dc));
+
+ // Use the generic, centered layout
+ } else {
+ View.setLayout(Rez.Layouts.MainLayout(dc));
+ }
+
+ var label = View.findDrawableById("label") as Text;
+ if (label != null) {
+ label.setText(Rez.Strings.label);
+ }
+ }
+
+ // The given info object contains all the current workout information.
+ // Calculate a value and save it locally in this method.
+ // Note that compute() and onUpdate() are asynchronous, and there is no
+ // guarantee that compute() will be called before onUpdate().
+ function compute(info as Activity.Info) as Void {
+ // See Activity.Info in the documentation for available information.
+ if (info has :currentHeartRate){
+ if(info.currentHeartRate != null){
+ hrValue = info.currentHeartRate as Number;
+ } else {
+ hrValue = 0;
+ }
+ }
+ if (info has :averageHeartRate){
+ if(info.averageHeartRate != null){
+ ahrValue = info.averageHeartRate as Number;
+ } else {
+ ahrValue = 0;
+ }
+ }
+ if (info has :maxHeartRate){
+ if(info.maxHeartRate != null){
+ mhrValue = info.maxHeartRate as Number;
+ } else {
+ mhrValue = 0;
+ }
+ }
+ }
+
+ // Display the value you computed here. This will be called
+ // once a second when the data field is visible.
+ function onUpdate(dc as Dc) as Void {
+ // Set the background color
+ (View.findDrawableById("Background") as Background).setColor(getBackgroundColor());
+
+ // HR value
+ var hrColor = calculateHRColor(hrValue);
+ var hr = View.findDrawableById("hr") as Text;
+ hr.setColor(hrColor);
+ hr.setText(hrValue.format("%d"));
+ var ahr = View.findDrawableById("ahr") as Text;
+ ahr.setText(ahrValue.format("%d"));
+ var mhr = View.findDrawableById("mhr") as Text;
+ mhr.setText(mhrValue.format("%d"));
+ var hrGraph = View.findDrawableById("HeartRate") as HeartRate;
+ hrGraph.setHRColor(hrColor);
+ hrGraph.setHRZones(hrZones);
+ hrGraph.setHRValue(hrValue);
+
+ // Set the foreground color and value
+ var value = View.findDrawableById("value") as Text;
+ if (value != null) {
+ if (getBackgroundColor() == Graphics.COLOR_BLACK) {
+ value.setColor(Graphics.COLOR_WHITE);
+ } else {
+ value.setColor(Graphics.COLOR_BLACK);
+ }
+ value.setText(hrValue.format("%d"));
+ }
+
+ // Call parent's onUpdate(dc) to redraw the layout
+ View.onUpdate(dc);
+ }
+
+}