var cron = require('cron-scheduler');
var gpio = require('pi-gpio');
var async = require('async');
var cronstuff = require('./cron');
var utils = require('./utils');

const HIGH = 1;
const LOW = 0;
const BUSY = true;
const FREE = false;
const OUTPUT = 'output';

//Object containing gpio pin, current value, and open status for the rooms
var mapRoomToPin = {
	'533': {
		openPin: 22,
		busyPin: 26,
		value: LOW,
		isOpen: false,
		isBusy: false
	},
	'537': {
		openPin: 18,
		busyPin: 24,
		value: LOW,
		isOpen: false,
		isBusy: false
	},
	'548': {
		openPin: 16,
		busyPin: 23,
		value: LOW,
		isOpen: false,
		isBusy: false
	},
	'550': {
		openPin: 15,
		busyPin: 21,
		pin: 15,
		value: LOW,
		isOpen: false,
		isBusy: false
	}
};

// Settings for cron
var cronObject = {
	timezone: 'America/New_York',
	on: '*/1 * * * *',
	name: 'update-leds'
};

// Run cron job
cron(cronObject, function() {
	console.log('cron started', Date.now());

	// Get latest room data
	utils.getRooms().then(function(rooms) {
		console.log('rooms: ');
		console.dir(rooms);

		// Asynchronously update each room's status
		async.each(rooms, function(room) {
			console.log('room: ');
			console.dir(room);

			var roomData = mapRoomToPin[room.number];

			console.log('roomdata: ');
			console.dir(roomData);

			// Check status and call function to write to pins
			console.log('room status: ', room.status);
			console.log('room value: ', roomData.value);
			if(room.status) { // && (roomData.value !==	HIGH)) {
				console.log('writing high to ' + roomData.busyPin);
				writeToPins(roomData, BUSY);
				} else { //if(roomData.value !== LOW) {
				writeToPins(roomData, FREE);
			}
		}, function(err) {
			if(err) {
				console.log('pi.js async.each error: ' + err);
			}
		});
	});

	console.log('cron finished', Date.now());
});

// determine which pins to write to based on bust state of the room
function writeToPins(roomData, value) {
	if(value) {
		//write high to busy, low to open
		writeHigh(roomData.busyPin);
		writeLow(roomData.openPin);
	} else {
		// write high to open, low to busy
		writeHigh(roomData.openPin);
		writeLow(roomData.busyPin);
	}
}

// Write high to pin
function writeHigh(pin) {
	gpioOpen(pin)
		.then(function() {
			gpioWrite(pin, HIGH);
		});
}

// Write low to pin
function writeLow(pin) {
	gpioOpen(pin).then(function() {
		gpioWrite(pin, LOW);
	});
}

function gpioOpen(pin) {
	return new Promise(function(resolve) {
		gpio.open(pin, OUTPUT, function(err) {
				if(err) {
					console.log('open error:');
					console.log(err);
				}
				console.log('done opening ', pin);
				resolve();
		});
	});
}

function gpioClose(pin) {
	gpio.close(pin, function(err) {
		if(err) {
			console.log('close error:');
			console.log(err);
		}
	});
}

function gpioWrite(pin, value) {
	gpio.write(pin, value, function(err) {
		if(err) {
			console.log('write error:');
			console.log(err);
		}
	});
}

// Check if a pin is open, if so close it...?
function closePinIfOpen(roomData, isOpen) {
	if(isOpen) {
		gpio.close(roomData.pin);
		roomData.isOpen = false;
		console.log('closing pin ' + roomData.pin);
	}

	return Promise.resolve();
}

console.log('pi started!');

@@ -2182,32 +2182,75 @@
 iteHigh(pin) %7B%0A%09
+gpioClose(pin).then(function () %7B%0A%09%09return 
 gpioOpen(pin)%0A%09%09
@@ -2246,19 +2246,21 @@
 pen(pin)
+;
 %0A%09
-%09
+%7D)
 .then(fu
@@ -2270,17 +2270,16 @@
 ion() %7B%0A
-%09
 %09%09gpioWr
@@ -2294,17 +2294,16 @@
  HIGH);%0A
-%09
 %09%7D);%0A%7D%0A%0A
@@ -2683,24 +2683,65 @@
 lose(pin) %7B%0A
+%09return new Promise(function(resolve) %7B%0A%09
 %09gpio.close(
@@ -2753,32 +2753,33 @@
 function(err) %7B%0A
+%09
 %09%09if(err) %7B%0A%09%09%09c
@@ -2769,32 +2769,33 @@
 %09%09%09if(err) %7B%0A%09%09%09
+%09
 console.log('clo
@@ -2802,32 +2802,33 @@
 se error:');%0A%09%09%09
+%09
 console.log(err)
@@ -2823,33 +2823,55 @@
 ole.log(err);%0A%09%09
-%7D
+%09%7D%0A%0A%09%09%09resolve();%0A%09%09%7D);
 %0A%09%7D);%0A%7D%0A%0Afunctio

promisify all gpio interactions