content: package dev.alt236.bluetoothlelib.device.beacon.ibeacon;
  
  import dev.alt236.bluetoothlelib.util.ByteUtils;
  
  final class IBeaconUtils {
      private static final double DISTANCE_THRESHOLD_WTF = 0.0;
      private static final double DISTANCE_THRESHOLD_IMMEDIATE = 0.5;
      private static final double DISTANCE_THRESHOLD_NEAR = 3.0;
  
      private IBeaconUtils(){
          // TO AVOID INSTANTIATION
      }
  
      /**
       * Calculates the accuracy of an RSSI reading.
       * <p/>
       * The code was taken from <a href="http://stackoverflow.com/questions/20416218/understanding-ibeacon-distancing" /a>
       *
       * @param txPower the calibrated TX power of an iBeacon
       * @param rssi    the RSSI value of the iBeacon
       * @return the calculated Accuracy
       */
      public static double calculateAccuracy(final int txPower, final double rssi) {
          if (rssi == 0) {
              return -1.0; // if we cannot determine accuracy, return -1.
          }
  
          final double ratio = rssi * 1.0 / txPower;
          if (ratio < 1.0) {
              return Math.pow(ratio, 10);
          } else {
              return (0.89976) * Math.pow(ratio, 7.7095) + 0.111;
          }
      }
  
      public static String calculateUuidString(final byte[] uuid) {
          final StringBuilder sb = new StringBuilder();
  
          for (int i = 0; i < uuid.length; i++) {
              if (i == 4) {
                  sb.append('-');
              }
              if (i == 6) {
                  sb.append('-');
              }
              if (i == 8) {
                  sb.append('-');
              }
              if (i == 10) {
                  sb.append('-');
              }
  
              final int intFromByte = ByteUtils.getIntFromByte(uuid[i]);
              if(intFromByte <= 0xF){
                  sb.append('0');
              }
              sb.append(Integer.toHexString(intFromByte));
          }
  
  
          return sb.toString();
      }
  
      public static IBeaconDistanceDescriptor getDistanceDescriptor(final double accuracy) {
          if (accuracy < DISTANCE_THRESHOLD_WTF) {
              return IBeaconDistanceDescriptor.UNKNOWN;
          }
  
          if (accuracy < DISTANCE_THRESHOLD_IMMEDIATE) {
              return IBeaconDistanceDescriptor.IMMEDIATE;
          }
  
          if (accuracy < DISTANCE_THRESHOLD_NEAR) {
              return IBeaconDistanceDescriptor.NEAR;
          }
  
          return IBeaconDistanceDescriptor.FAR;
      }
  }
  