var Tinkerforge = require('../Tinkerforge')
,   Conf        = require('./config.json')
,   Helper      = require('../Adawim/helper')
,   Log         = require('../Adawim/logging')
,   http        = require('http');


Helper.each(Conf.items, function(item) {
  connect(item);
});

var lastTagID = '';
var timeOutForHoldingLastTagID = null;
const timeOutForHoldingLastTagIDInMillis = 5000;

/* private */
function reconnect(item) {
  Log.debug('Reconnect ' + item.host);
  setTimeout(function() { connect(item) }, 10000);
}

/* private */
function connect(item) {
  var HOST = item.host;
  var PORT = item.port;
  var UID = item.uid;

  Log.log('Init ' + UID + ' @' + HOST);
  
  var ipcon = new Tinkerforge.IPConnection(); // Create IP connection
  
  var counter = 0;
  var readyForNextNotification = true;
  
  ipcon.connect(HOST, PORT,
    function (error) {
    
      /*
        IPConnection.ERROR_ALREADY_CONNECTED = 11
        IPConnection.ERROR_NOT_CONNECTED = 12
        IPConnection.ERROR_CONNECT_FAILED = 13
        IPConnection.ERROR_INVALID_FUNCTION_ID = 21
        IPConnection.ERROR_TIMEOUT = 31
        IPConnection.ERROR_INVALID_PARAMETER = 41
        IPConnection.ERROR_FUNCTION_NOT_SUPPORTED = 42
        IPConnection.ERROR_UNKNOWN_ERROR = 43
      */

      Log.error('Error @'+HOST+': ' + error);
      
      if(error === 13) {
        reconnect(item);
      }
    }
  ); // Connect to brickd
  // Don't use device before ipcon is connected
  
  ipcon.on(Tinkerforge.IPConnection.CALLBACK_CONNECTED,
    function (connectReason) {

      switch(connectReason) {
      case Tinkerforge.IPConnection.CONNECT_REASON_REQUEST:
        Log.log('Connect by request for '+UID+' @'+HOST);
        break;
      case Tinkerforge.IPConnection.CONNECT_REASON_AUTO_RECONNECT:
        Log.log('Connect by auto-reconnect for '+UID+' @'+HOST);
        break;
      }

      connectRFIDReader(item, ipcon);
    }
  );
  
  process.on( 'SIGINT', function() {
    Log.log( "Gracefully disconnect " + HOST );
    ipcon.disconnect();
    process.exit( );
  });
}

/* private */
function connectRFIDReader(item, ipcon) {
  var UID = item.uid;
  var nr = new Tinkerforge.BrickletNFCRFID(UID, ipcon); // Create device object
  var tagType = 0;
  
  // start scan loop
  nr.requestTagID(Tinkerforge.BrickletNFCRFID.TAG_TYPE_MIFARE_CLASSIC);
  
  // Register state changed callback
  nr.on(Tinkerforge.BrickletNFCRFID.CALLBACK_STATE_CHANGED,
    // Callback function for state changed callback
    
    /*
      STATE:
      BrickletNFCRFID.STATE_INITIALIZATION = 0
      BrickletNFCRFID.STATE_IDLE = 128
      BrickletNFCRFID.STATE_ERROR = 192
      BrickletNFCRFID.STATE_REQUEST_TAG_ID = 2
      BrickletNFCRFID.STATE_REQUEST_TAG_ID_READY = 130
      BrickletNFCRFID.STATE_REQUEST_TAG_ID_ERROR = 194
      BrickletNFCRFID.STATE_AUTHENTICATING_MIFARE_CLASSIC_PAGE = 3
      BrickletNFCRFID.STATE_AUTHENTICATING_MIFARE_CLASSIC_PAGE_READY = 131
      BrickletNFCRFID.STATE_AUTHENTICATING_MIFARE_CLASSIC_PAGE_ERROR = 195
      BrickletNFCRFID.STATE_WRITE_PAGE = 4
      BrickletNFCRFID.STATE_WRITE_PAGE_READY = 132
      BrickletNFCRFID.STATE_WRITE_PAGE_ERROR = 196
      BrickletNFCRFID.STATE_REQUEST_PAGE = 5
      BrickletNFCRFID.STATE_REQUEST_PAGE_READY = 133
      BrickletNFCRFID.STATE_REQUEST_PAGE_ERROR = 197
    */
    
    function (state, idle) {
      if(idle) {
        tagType = (tagType + 1) % 3;
        nr.requestTagID(tagType);
      }

      if(state == Tinkerforge.BrickletNFCRFID.STATE_REQUEST_TAG_ID_READY) {
        nr.getTagID(
          function (tagType, tidLength, tid) {
            var s = 'Found tag of type ' + tagType +
                    ' with ID [' + tid[0].toString(16);
            var tagID = tid[0].toString(16);

            for(var i = 1; i < tidLength; i++) {
              s += ' ' + tid[i].toString(16);
              tagID += ' ' + tid[i].toString(16);
            }

            s += ']';
            
            if(lastTagID !== tagID) {
              Log.log(s);
              lastTagID = tagID;
              
              clearTimeout(timeOutForHoldingLastTagID);
              timeOutForHoldingLastTagID = setTimeout(function() { lastTagID = ''; }, timeOutForHoldingLastTagIDInMillis);
            }
          },
          function (error) {
            Log.error('Error: ' + error);
          }
        );
      }
    }
  );
}