<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
  <title>View/Create/Delete Particle Access Tokens</title>

  <!-- Bootstrap -->
  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">

  <!-- Styles -->
  <link href="style.css" rel="stylesheet">

  <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
  <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
  <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>

<body>

  <!-- login modal -->
  <div id="login-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="loginModal" aria-hidden="true">
    <div class="modal-dialog modal-sm">
      <div class="modal-content">
        <div class="modal-header">
          <h4 class="modal-title">Particle login</h4>
        </div>
        <div class="modal-body">
          <div class="alert alert-danger" role="alert">
            <p>Check your login details.</p>
          </div>
          <form id="particle-login">
            <div class="form-group">
              <label class="sr-only" for="emailAddress">Email address</label>
              <input name="username" type="email" class="form-control" id="emailAddress" placeholder="Email address">
            </div>
            <div class="form-group">
              <label class="sr-only" for="password">Password</label>
              <input name="password" password="password" type="password" class="form-control" id="password" placeholder="Password">
            </div>
            <button type="submit" class="btn btn-primary btn-block">Log in</button>
          </form>
        </div>
      </div>
    </div>
  </div>
  
  <!-- devices modal -->
    <div id="devices-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="devicesModal" aria-hidden="true">
      <div class="modal-dialog modal-sm">
        <div class="modal-content">
          <div class="modal-header">
            <h4 class="modal-title">Choose device</h4>
          </div>
          <div class="modal-body">
              <form id="particle-devices">

                <div class="panel panel-default">
                  <ul class="list-group">
                  </ul>
                </div>

                <button id="btn-flash-device" type="submit" class="btn btn-primary btn-block" disabled="disabled">Flash firmware</button>
              </form>
          </div>
          <div class="modal-footer">
            <button id="btn-close-device-modal" type="button" class="btn btn-primary" data-dismiss="modal" disabled="disabled">Close</button>
          </div>
        </div>
      </div>
    </div>

  <div class="container">

  </div>

  <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
  <!-- Include all compiled plugins (below), or include individual files as needed -->
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
  <script src="script.js"></script>
</body>

</html>
// display login modal
$('#login-modal').modal({
  'backdrop': 'static'
});

// login functionality
$('#particle-login').submit(function(e) {

  // get contents of login form (email, password)
  var auth = $(this).serializeArray();

  // create instance of particle token object (see below)
  var particle = new Particle(auth[0].value, auth[1].value);

  particle.createAccessToken(function(accessToken) {

    // hide login modal
    $('#login-modal').modal('hide');

    // display device selection modal
    $('#devices-modal').modal({
      'backdrop': 'static'
    });

    particle.listDevices(accessToken, function(devices) {

      // populate modal with list of devices
      $.each(devices, function(k, v) {
        $('#particle-devices .list-group').append(
          '<li class="list-group-item">' +
          '<div class="radio">' +
          '<label>' +
          '<input type="radio" name="optionsCores" id="optionsCores' + k + '" value="' + v.id + '">' + v.name +
          '</label>' +
          '</div>' +
          '</li>'
        );
      });

      // select device
      $('#particle-devices').on('change', function() {

        // get select device
        var device = $(this).serializeArray();

        // enable flash and close buttons
        $('#btn-flash-device').prop('disabled', false);
        $('#btn-close-device-modal').prop('disabled', false);

        // flash device
        $('#btn-flash-device').click(function(e) {
          particle.flashDevice(device[0].value, accessToken);

          e.preventDefault();
        });
      });

    });
  });

  e.preventDefault();
});

// particle object
var Particle = function(username, password) {

  this.getAccessTokens = function(success, error) {
    $.ajax({
      method: "GET",
      url: "https://api.particle.io/v1/access_tokens",
      beforeSend: function(xhr) {
        // authorization header uses a base64 hash of email and password
        xhr.setRequestHeader('Authorization', 'Basic ' + btoa(username + ':' + password));
      },
      success: function(accessTokens) {
        if (success) success(accessTokens);
      },
      error: function(error) {
        if (error) error();
      }
    })
  };

  this.createAccessToken = function(success, error) {
    $.ajax({
      method: "POST",
      url: "https://api.particle.io/oauth/token",
      data: {
        'grant_type': 'password',
        'username': username,
        'password': password
      },
      beforeSend: function(xhr) {
        xhr.setRequestHeader('Authorization', 'Basic ' + btoa('particle:particle'));
      },
      success: function(accessToken) {
        if (success) success(accessToken.access_token);
      },
      error: function(error) {
        if (error) error();
      }
    })
  };

  this.deleteAccessToken = function(accessToken, success) {
    $.ajax({
      method: "DELETE",
      url: "https://api.particle.io/v1/access_tokens/" + accessToken,
      beforeSend: function(xhr) {
        xhr.setRequestHeader('Authorization', 'Basic ' + btoa(username + ':' + password));
      },
      success: function() {
        if (success) success();
      }
    });
  };

  this.listDevices = function(accessToken, success) {
    $.ajax({
      method: "GET",
      url: "https://api.particle.io/v1/devices",
      data: {
        'access_token': accessToken
      },
      success: function(devices) {
        if (success) success(devices);
      }
    });
  };

  this.flashDevice = function(deviceId, accessToken) {
    $.ajax({
      method: "GET",
      
      // url needs to be absolute to work in plnkr - hosted version should be relative url ("/firmware.ino") - this script will not work in a local environment
      url: "http://run.plnkr.co/plunks/2M41bLuuEguGoFjqWVqj/firmware.ino",
      success: function(file) {

        // create file
        var f = new File([file], "firmware.ino");

        // create form-data object and add file to it
        var form = new FormData();
        form.append("file", f);

        // put firmware onto device
        $.ajax({
          async: true,
          crossDomain: true,
          url: "https://api.particle.io/v1/devices/" + deviceId + "?access_token=" + accessToken,
          method: "PUT",
          headers: {},
          processData: false,
          contentType: false,
          mimeType: "multipart/form-data",
          data: form
        });
      }
    });
  };

};
body {
  margin-top: 20px;
}

.alert,
#access-tokens,
#access-token-btn {
  display: none;
}
int timeOn = 0;
int timeOff = 2000;

void setup() {
    Spark.function("ssr", ssrControl);
    pinMode(D7, OUTPUT);
}

void loop() {
    delay(timeOff);
    digitalWrite(D7, HIGH);
    delay(timeOn);
    digitalWrite(D7, LOW);
}

int ssrControl(String t) {
    timeOn = atoi(t.c_str());
    timeOff = 2000-timeOn;
    return 1;
}