private static void paintArrowsInGraph(
     Canvas canvas,
     SpotWindData spotWindData,
     Images images,
     int startX,
     int endX,
     int xSteps,
     int startY,
     int endY,
     int stepXCount) {
   Paint paint = new Paint();
   int hourPos = 0;
   for (int x = startX; x <= endX; x += xSteps) {
     canvas.drawLine(x, startY, x, endY, paint);
     WindData windData = spotWindData.getWindData(hourPos);
     if (windData != null) {
       Matrix arrowImageMatrix = new Matrix();
       float origArrowSize = images.getArrowBitmap().getHeight();
       int arrowSize = 30;
       float arrowScale = arrowSize / origArrowSize;
       int rotation = windData.getAngle();
       arrowImageMatrix.postScale(arrowScale, arrowScale);
       arrowImageMatrix.postRotate(rotation, arrowSize / 2, arrowSize / 2);
       arrowImageMatrix.postTranslate(x - arrowSize / 2, startY + 5);
       canvas.drawBitmap(images.getArrowBitmap(), arrowImageMatrix, paint);
     }
     hourPos += 24 / stepXCount;
   }
 }
  private static void paintImageText(
      Context context,
      WidgetLayoutDetails widgetLayoutDetails,
      Canvas canvas,
      WindData windData,
      int xOffset,
      int yOffset) {
    int xPosText = xOffset + (int) widgetLayoutDetails.spotImageHeight + 30;
    int yPosTextTime = yOffset + (int) (widgetLayoutDetails.spotImageHeight / 4) * 1;
    int yPosTextWind = yOffset + (int) (widgetLayoutDetails.spotImageHeight / 4) * 2;
    int yPosTextAngle = yOffset + (int) (widgetLayoutDetails.spotImageHeight / 4) * 3;

    // paint text data
    Paint textPaint = new Paint();
    textPaint.setColor(Color.DKGRAY);
    textPaint.setTextSize(30);

    String timeStr = context.getResources().getString(R.string.graphics_no_data);
    String windStr = context.getResources().getString(R.string.graphics_no_data);
    String angleStr = context.getResources().getString(R.string.graphics_no_data);
    if (windData != null) {
      int wind = (int) Math.round(windData.getWind());
      int gust = (int) Math.round(windData.getGust());
      timeStr = windData.getTimeStr();
      windStr = wind + " - " + gust + " " + context.getResources().getString(R.string.graphics_mps);
      angleStr =
          windData.getAngle() + " " + context.getResources().getString(R.string.graphics_degrees);
    }

    canvas.drawText(timeStr, xPosText, yPosTextTime, textPaint);
    canvas.drawText(windStr, xPosText, yPosTextWind, textPaint);
    canvas.drawText(angleStr, xPosText, yPosTextAngle, textPaint);
  }
  private static void paintArrow(
      Canvas canvas,
      WidgetLayoutDetails widgetLayoutDetails,
      Images images,
      WindData windData,
      int xOffset,
      int yOffset) {
    Paint paint = new Paint();
    Matrix arrowImageMatrix = new Matrix();
    float origArrowSize = images.getArrowBitmap().getHeight();
    float arrowScale = widgetLayoutDetails.spotImageHeight / origArrowSize;
    float scaleForWind = (float) windData.getWind() / MAXWIND;
    if (scaleForWind > 1) scaleForWind = 1;
    int rotation = windData.getAngle();
    double arrowHeight = widgetLayoutDetails.spotImageHeight * scaleForWind;
    int offset = ((int) widgetLayoutDetails.spotImageHeight - (int) arrowHeight) / 2;

    arrowImageMatrix.postScale(arrowScale, arrowScale);
    arrowImageMatrix.postRotate(
        rotation, widgetLayoutDetails.spotImageHeight / 2, widgetLayoutDetails.spotImageHeight / 2);
    arrowImageMatrix.postScale(scaleForWind, scaleForWind);
    arrowImageMatrix.postTranslate(offset, offset);
    arrowImageMatrix.postTranslate(xOffset, yOffset);
    canvas.drawBitmap(images.getArrowBitmap(), arrowImageMatrix, paint);
  }
 private static WIND_DIRECTORION calculateWindAngleStatus(
     WindData windData, SpotWindData spotWindData) {
   int angleDiff = windData.getAngle() - spotWindData.getSpotData().getLocationDirection();
   // when angle diff < -180, then add 360
   if (angleDiff < -180) angleDiff += 360;
   // make absolute
   if (angleDiff < 0) angleDiff = angleDiff * -1;
   // check wind direction
   if (angleDiff <= 85) return WIND_DIRECTORION.AANLANDIG;
   if ((angleDiff > 85) && (angleDiff <= 95)) return WIND_DIRECTORION.SIDESHORE;
   if (angleDiff > 95) return WIND_DIRECTORION.AFLANDIG;
   return WIND_DIRECTORION.AFLANDIG; // should never happen
 }
 public void InsertWindStat(WindData windStat, DbHandle handle) {
   SQLiteDatabase db = handle.getDb();
   ContentValues cv = new ContentValues();
   cv.put(COL_SPOT, windStat.getSpotID());
   cv.put(COL_DAY, windStat.getDay());
   cv.put(COL_HOUR, windStat.getEndHour());
   cv.put(COL_MINUTE, windStat.getEndMinute());
   cv.put(COL_START_HOUR, windStat.getStartHour());
   cv.put(COL_START_MINUTE, windStat.getStartMinute());
   cv.put(COL_WIND, windStat.getWind());
   cv.put(COL_GUST, windStat.getGust());
   cv.put(COL_ANGLE, windStat.getAngle());
   cv.put(COL_LAST_MODIFIED, windStat.getLastModified());
   db.insert(WINDTABLE, null, cv);
 }
 public void UpdateWindStat(WindData windStat, int id, DbHandle handle) {
   SQLiteDatabase db = handle.getDb();
   ContentValues cv = new ContentValues();
   cv.put(COL_DAY, windStat.getDay());
   cv.put(COL_SPOT, windStat.getSpotID());
   cv.put(COL_HOUR, windStat.getEndHour());
   cv.put(COL_MINUTE, windStat.getEndMinute());
   cv.put(COL_START_HOUR, windStat.getStartHour());
   cv.put(COL_START_MINUTE, windStat.getStartMinute());
   cv.put(COL_WIND, windStat.getWind());
   cv.put(COL_GUST, windStat.getGust());
   cv.put(COL_ANGLE, windStat.getAngle());
   cv.put(COL_LAST_MODIFIED, windStat.getLastModified());
   db.update(WINDTABLE, cv, COL_ID + "=?", new String[] {"" + id});
 }
  private static WIND_POWER calculateWindPower(Context context, WindData windData) {
    if (windData.getAngle() == -1 || windData.getWind() == -1 || windData.getGust() == -1) {
      return WIND_POWER.OUTDATED;
    }

    double wind = windData.getWind();
    double minWind = LocalStorage.getMinimalWind(context);
    double optimalWind = LocalStorage.getOptimalWind(context);
    double muchWind = LocalStorage.getMuchWind(context);
    double tooMuchWind = LocalStorage.getToomuchWind(context);

    if (wind <= minWind) return WIND_POWER.TOO_SHORT;
    if ((wind > minWind) && (wind <= optimalWind)) return WIND_POWER.OK;
    if ((wind > optimalWind) && (wind <= muchWind)) return WIND_POWER.GOOD;
    if ((wind > muchWind) && (wind <= tooMuchWind)) return WIND_POWER.WARNING;
    if (wind > tooMuchWind) return WIND_POWER.DANGER;
    return WIND_POWER.DANGER; // should never happen
  }