private void drawSunArrow(Graphics g, float angle, Color col, float scale) {
    float angleRad = (angle) * (float) java.lang.Math.PI / 180;
    int centerX = location.width / 2, centerY = location.height / 2;
    float arrowLength = roseRadius * scale;
    float halfArrowWidth = arrowLength * 0.08f;
    float circlePos = arrowLength * 0.7f;
    int circleRadius = (int) (arrowLength * 0.1f);

    int circleX = centerX + new Float(circlePos * java.lang.Math.sin(angleRad)).intValue();
    int circleY = centerY - new Float(circlePos * java.lang.Math.cos(angleRad)).intValue();

    int[] pointsX = new int[4];
    int[] pointsY = new int[4];

    pointsX[0] = centerX + new Float(arrowLength * java.lang.Math.sin(angleRad)).intValue();
    pointsY[0] = centerY - new Float(arrowLength * java.lang.Math.cos(angleRad)).intValue();
    pointsX[1] =
        centerX
            + new Float(halfArrowWidth * java.lang.Math.sin(angleRad + java.lang.Math.PI / 2.0))
                .intValue();
    pointsY[1] =
        centerY
            - new Float(halfArrowWidth * java.lang.Math.cos(angleRad + java.lang.Math.PI / 2.0))
                .intValue();
    pointsX[2] =
        centerX
            + new Float(halfArrowWidth * java.lang.Math.sin(angleRad + java.lang.Math.PI))
                .intValue();
    pointsY[2] =
        centerY
            - new Float(halfArrowWidth * java.lang.Math.cos(angleRad + java.lang.Math.PI))
                .intValue();
    pointsX[3] =
        centerX
            + new Float(halfArrowWidth * java.lang.Math.sin(angleRad - java.lang.Math.PI / 2.0))
                .intValue();
    pointsY[3] =
        centerY
            - new Float(halfArrowWidth * java.lang.Math.cos(angleRad - java.lang.Math.PI / 2.0))
                .intValue();

    // g.setPen(new Pen(col,Pen.SOLID,3));
    // g.drawLine(centerX,centerY,pointX,pointY);

    g.setPen(new Pen(Color.Black, Pen.SOLID, 1));
    g.setBrush(new Brush(col, Brush.SOLID));
    g.fillPolygon(pointsX, pointsY, 4);
    g.fillEllipse(
        circleX - circleRadius, circleY - circleRadius, 2 * circleRadius, 2 * circleRadius);
  }
 public void doPaintSquare(Graphics g) {
   int h = height;
   g.setColor(bgColor);
   int bx = text.length() == 0 ? 0 : 2;
   int by = text.length() == 0 ? 0 : (h - boxWidth) / 2 + 1;
   g.fillRect(bx + 2, by + 2, boxWidth - 4, boxWidth - 4);
   if (state || pressState) {
     Color c = Color.LightGray;
     if (!pressState) {
       if (!state) c = bgColor;
       else c = Color.Black;
     }
     Pen oldpen = g.setPen(new Pen(c, Pen.SOLID, 2));
     g.drawLine(bx + 4, by + boxWidth - 5, bx + boxWidth - 5, by + 4);
     g.drawLine(bx + 4, by + boxWidth - 5, bx + 4, by + boxWidth - 10);
     //				g.drawLine(bx+3,by+3,bx+boxWidth-5,by+boxWidth-5);
     //				g.drawLine(bx+3,by+boxWidth-5,bx+boxWidth-5,by+3);
     g.setPen(oldpen);
   }
   g.draw3DRect(
       new Rect(bx, by, boxWidth, boxWidth),
       ButtonObject.checkboxEdge,
       true,
       null,
       Color.DarkGray);
 }
  private void drawGpsStatus(Graphics g) {
    if ((m_fix > 0) && (m_sats >= 0)) {
      // Set background to signal quality
      g.setColor(GREEN);
    } else
    // receiving data, but signal ist not good
    if ((m_fix == 0) && (m_sats >= 0)) {
      g.setColor(YELLOW);
    } else {
      g.setColor(RED);
    }

    String strSats = "Sats: -";
    if (m_sats >= 0) {
      strSats = "Sats: " + Convert.toString(m_sats) + "/" + Convert.toString(m_satsInView);
    }
    String strHdop = "HDOP: -";
    if (m_hdop >= 0) strHdop = "HDOP: " + Convert.toString(m_hdop);

    int textWidth = java.lang.Math.max(fm.getTextWidth(strSats), fm.getTextWidth(strHdop));
    int startX = location.width - (textWidth + 4);
    int startY = location.height - 2 * lineHeight;
    g.fillRect(startX, startY, location.width - startX, location.height - startY);

    g.setColor(Color.Black);
    g.drawText(strSats, startX + 2, startY);
    g.drawText(strHdop, startX + 2, startY + lineHeight);
  }
  private void drawLuminaryData(Graphics g) {
    g.setColor(YELLOW);

    String strSunDir = "---" + " " + MyLocale.getMsg(1502, "deg");
    if (sunDir < 360 && sunDir > -360) {
      Double tmp = new Double();
      tmp.set(sunDir);
      strSunDir = tmp.toString(0, 0, 0) + " " + MyLocale.getMsg(1502, "deg");
    }

    int textWidth = java.lang.Math.max(fm.getTextWidth(m_Luminary), fm.getTextWidth(strSunDir));
    int startY = location.height - 2 * lineHeight;
    g.fillRect(0, startY, textWidth + 4, location.height - startY);

    g.setColor(Color.Black);
    g.drawText(m_Luminary, 2, startY);
    g.drawText(strSunDir, 2, startY + lineHeight);
  }
  private void drawThickArrow(Graphics g, float angle, Color col, float scale) {
    float angleRad = (angle) * (float) java.lang.Math.PI / 180;
    int centerX = location.width / 2, centerY = location.height / 2;
    float arrowLength = roseRadius * scale;
    float halfArrowWidth = arrowLength * 0.1f;

    int[] pointsX = new int[4];
    int[] pointsY = new int[4];

    pointsX[0] = centerX + new Float(arrowLength * java.lang.Math.sin(angleRad)).intValue();
    pointsY[0] = centerY - new Float(arrowLength * java.lang.Math.cos(angleRad)).intValue();
    pointsX[1] =
        centerX
            + new Float(halfArrowWidth * java.lang.Math.sin(angleRad + java.lang.Math.PI / 2.0))
                .intValue();
    pointsY[1] =
        centerY
            - new Float(halfArrowWidth * java.lang.Math.cos(angleRad + java.lang.Math.PI / 2.0))
                .intValue();
    pointsX[2] =
        centerX
            + new Float(halfArrowWidth * java.lang.Math.sin(angleRad + java.lang.Math.PI))
                .intValue();
    pointsY[2] =
        centerY
            - new Float(halfArrowWidth * java.lang.Math.cos(angleRad + java.lang.Math.PI))
                .intValue();
    pointsX[3] =
        centerX
            + new Float(halfArrowWidth * java.lang.Math.sin(angleRad - java.lang.Math.PI / 2.0))
                .intValue();
    pointsY[3] =
        centerY
            - new Float(halfArrowWidth * java.lang.Math.cos(angleRad - java.lang.Math.PI / 2.0))
                .intValue();

    g.setPen(new Pen(Color.Black, Pen.SOLID, 1));
    g.setBrush(new Brush(col, Brush.SOLID));
    g.fillPolygon(pointsX, pointsY, 4);
  }
  private void drawThinArrow(Graphics g, float angle, Color col, Color colPoint, float scale) {
    float angleRad = (angle) * (float) java.lang.Math.PI / 180;
    int centerX = location.width / 2, centerY = location.height / 2;
    float arrowLength = roseRadius * scale;
    float halfOpeningAngle = (float) (java.lang.Math.PI * 0.03);
    float sideLineLength = arrowLength * 0.75f;

    int[] pointsX = new int[4];
    int[] pointsY = new int[4];

    pointsX[0] =
        centerX
            + new Float(sideLineLength * java.lang.Math.sin(angleRad - halfOpeningAngle))
                .intValue();
    pointsY[0] =
        centerY
            - new Float(sideLineLength * java.lang.Math.cos(angleRad - halfOpeningAngle))
                .intValue();
    pointsX[1] = centerX + new Float(arrowLength * java.lang.Math.sin(angleRad)).intValue();
    pointsY[1] = centerY - new Float(arrowLength * java.lang.Math.cos(angleRad)).intValue();
    pointsX[2] =
        centerX
            + new Float(sideLineLength * java.lang.Math.sin(angleRad + halfOpeningAngle))
                .intValue();
    pointsY[2] =
        centerY
            - new Float(sideLineLength * java.lang.Math.cos(angleRad + halfOpeningAngle))
                .intValue();
    pointsX[3] = centerX;
    pointsY[3] = centerY;

    g.setPen(new Pen(Color.Black, Pen.SOLID, 1));
    g.setBrush(new Brush(col, Brush.SOLID));
    g.fillPolygon(pointsX, pointsY, 4);
    if (colPoint != null) {
      g.setBrush(new Brush(colPoint, Brush.SOLID));
      g.fillPolygon(pointsX, pointsY, 3);
    }
  }
  public static Font GetCorrectedFont(Graphics g, String name, int style, int size) {
    Font newFont = new Font(name, style, size);
    FontMetrics metrics = g.getFontMetrics(newFont);
    int fontHeight = metrics.getHeight();

    float ratio = (float) fontHeight / (float) size;
    if (ratio < 0.9 || ratio > 1.1) {
      size = (int) (size / ratio + 0.5);
      if (size < 5) size = 5;
      newFont = new Font(name, style, size);
    }

    return newFont;
  }
  private void drawWayPointData(Graphics g) {
    String strTemp = MyLocale.getMsg(1512, "Waypoint");
    g.setColor(Color.DarkBlue);
    g.fillRect(0, 0, fm.getTextWidth(strTemp) + 4, lineHeight);
    g.setColor(Color.White);
    g.drawText(strTemp, 2, 0);

    g.setColor(Color.Black);

    int metricSystem = Global.getPref().metricSystem;
    Double tmp = new Double();
    strTemp = "";
    double newDistance = 0;
    int bigUnit = -1;
    int smallUnit = -1;
    double threshold = -1;
    // Allow for different metric systems
    if (metricSystem == Metrics.IMPERIAL) {
      // Why these values? See: http://tinyurl.com/b4nn9m
      bigUnit = Metrics.MILES;
      smallUnit = Metrics.FEET;
      threshold = 0.1;
      newDistance = Metrics.convertUnit(distance, Metrics.KILOMETER, Metrics.MILES);
    } else {
      bigUnit = Metrics.KILOMETER;
      smallUnit = Metrics.METER;
      threshold = 1.0;
      newDistance = distance;
    }
    if (newDistance >= 0.0f) {
      tmp.set(newDistance);
      if (tmp.value >= threshold) {
        strTemp = MyLocale.formatDouble(tmp, "0.000") + " " + Metrics.getUnit(bigUnit);
      } else {
        tmp.set(Metrics.convertUnit(tmp.value, bigUnit, smallUnit));
        strTemp = tmp.toString(3, 0, 0) + " " + Metrics.getUnit(smallUnit);
      }
    } else strTemp = "--- " + Metrics.getUnit(bigUnit);
    g.drawText(strTemp, 2, lineHeight);

    tmp.set(gotoDir);
    if ((tmp.value <= 360) && (tmp.value >= -360))
      strTemp = tmp.toString(0, 0, 0) + " " + MyLocale.getMsg(1502, "deg");
    else strTemp = "---" + " " + MyLocale.getMsg(1502, "deg");
    g.drawText(strTemp, 2, 2 * lineHeight);
  }
  private void drawGpsData(Graphics g) {
    g.setColor(RED);

    String strHeadline = MyLocale.getMsg(1501, "Current");

    Double tmp = new Double();

    String strSpeed = null;
    String unit = null;

    // Allow for different metric systems
    if (Global.getPref().metricSystem == Metrics.IMPERIAL) {
      tmp.set(Metrics.convertUnit(m_speed, Metrics.KILOMETER, Metrics.MILES));
      unit = " mph";
      strSpeed = "- mph";
    } else {
      tmp.set(m_speed);
      unit = " km/h";
      strSpeed = "- km/h";
    }
    if (tmp.value >= 0) {
      if (tmp.value >= 100) {
        strSpeed = MyLocale.formatDouble(tmp, "0") + unit;
      } else {
        strSpeed = MyLocale.formatDouble(tmp, "0.0") + unit;
      }
    }

    tmp.set(moveDir);
    String strMoveDir = "---" + " " + MyLocale.getMsg(1502, "deg");
    if ((tmp.value <= 360) && (tmp.value >= -360))
      strMoveDir = tmp.toString(0, 0, 0) + " " + MyLocale.getMsg(1502, "deg");

    int textWidth = java.lang.Math.max(fm.getTextWidth(strSpeed), fm.getTextWidth(strMoveDir));
    textWidth = java.lang.Math.max(textWidth, fm.getTextWidth(strHeadline));

    int startX = location.width - (textWidth + 4);
    g.fillRect(startX, 0, location.width - startX, lineHeight);

    g.setColor(Color.Black);
    g.drawText(strHeadline, startX + 2, 0);
    g.drawText(strSpeed, startX + 2, lineHeight);
    g.drawText(strMoveDir, startX + 2, 2 * lineHeight);
  }
  /**
   * draw arrows for the directions of movement and destination waypoint
   *
   * @param ctrl the control to paint on
   * @param moveDir degrees of movement
   * @param destDir degrees of destination waypoint
   */
  public void doDraw(Graphics g, int options) {
    g.setColor(Color.White);
    g.fillRect(0, 0, location.width, location.height);

    int fontSize = location.width / 17;
    mainFont = GetCorrectedFont(g, "Verdana", Font.BOLD, fontSize);
    g.setFont(mainFont);
    fm = g.getFontMetrics(mainFont);
    lineHeight = fm.getHeight() + 1;
    roseRadius = java.lang.Math.min((location.width * 3) / 4, location.height) / 2;

    if (northCentered) {
      // scale(location.width, location.height, null, 0);
      // super.doDraw(g, options);
      drawFullRose(
          g,
          0,
          new Color(255, 255, 255),
          new Color(200, 200, 200),
          new Color(255, 255, 255),
          new Color(200, 200, 200),
          new Color(150, 150, 150),
          new Color(75, 75, 75),
          1.0f,
          true,
          true);
    } else {
      int radius = (int) (roseRadius * 0.75f);

      g.setPen(new Pen(new Color(150, 150, 150), Pen.SOLID, 3));
      g.drawEllipse(
          location.width / 2 - radius, location.height / 2 - radius, 2 * radius, 2 * radius);
    }

    drawArrows(g);
    drawWayPointData(g);
    drawGpsData(g);
    drawLuminaryData(g);
    drawGpsStatus(g);
  }
  private void drawArrows(Graphics g) {
    if (g != null) {
      // select moveDirColor according to difference to gotoDir
      Color moveDirColor = RED;

      if (gotoDir < 360 && gotoDir > -360 && moveDir < 360 && moveDir > -360) {
        float diff = java.lang.Math.abs(moveDir - gotoDir);
        while (diff > 360) {
          diff -= 360.0f;
        }
        if (diff > 180.0f) {
          diff = 360.0f - diff;
        }

        if (diff <= 12.25f) {
          moveDirColor = GREEN;
        } else if (diff <= 22.5f) {
          moveDirColor = CYAN;
        } else if (diff <= 45.0f) {
          moveDirColor = ORANGE;
        } else if (diff <= 90.0f) {
          moveDirColor = MAGENTA;
        }
      }

      // draw only valid arrows
      if (northCentered) {
        if (gotoDir < 360 && gotoDir > -360) drawThickArrow(g, gotoDir, Color.DarkBlue, 1.0f);
        if (moveDir < 360 && moveDir > -360) drawThinArrow(g, moveDir, RED, moveDirColor, 1.0f);
        if (sunDir < 360 && sunDir > -360) drawSunArrow(g, sunDir, YELLOW, 0.75f);
      } else {
        // moveDir centered
        if (moveDir < 360 && moveDir > -360) {
          // drawDoubleArrow(g, 360 - moveDir, BLUE, new Color(175,0,0), 1.0f);
          // drawRose(g, 360 - moveDir, new Color(100,100,100), new Color(200,200,200), 1.0f);
          drawFullRose(
              g,
              360 - moveDir,
              new Color(255, 255, 255),
              new Color(200, 200, 200),
              new Color(150, 150, 150),
              new Color(200, 200, 200),
              new Color(200, 200, 200),
              new Color(75, 75, 75),
              1.0f,
              false,
              false);

          int radius = (int) (roseRadius * 0.75f);
          g.setPen(new Pen(RED, Pen.SOLID, 3));
          g.drawLine(
              location.width / 2,
              location.height / 2 - radius,
              location.width / 2,
              location.height / 2 + radius);

          if (gotoDir < 360 && gotoDir > -360)
            drawThinArrow(g, gotoDir - moveDir, Color.DarkBlue, moveDirColor, 1.0f);
          if (sunDir < 360 && sunDir > -360) drawSunArrow(g, sunDir - moveDir, YELLOW, 0.75f);
        }
      }
    }
  }
  private void drawRosePart(
      Graphics g,
      float angle,
      Color colLeft,
      Color colRight,
      Color colBorder,
      Color colText,
      float scale,
      float innerScale,
      String strDir,
      boolean bDrawText) {
    float angleRad = angle * (float) java.lang.Math.PI / 180;
    float angleRadText = (angle + 7.5f) * (float) java.lang.Math.PI / 180;
    int centerX = location.width / 2, centerY = location.height / 2;

    float arrowLength = roseRadius * scale;
    float halfArrowWidth = arrowLength * innerScale;

    int[] pointsX = new int[3];
    int[] pointsY = new int[3];

    pointsX[0] = centerX;
    pointsY[0] = centerY;
    pointsX[1] = centerX + new Float(arrowLength * java.lang.Math.sin(angleRad)).intValue();
    pointsY[1] = centerY - new Float(arrowLength * java.lang.Math.cos(angleRad)).intValue();
    pointsX[2] =
        centerX
            + new Float(halfArrowWidth * java.lang.Math.sin(angleRad - java.lang.Math.PI / 4.0))
                .intValue();
    pointsY[2] =
        centerY
            - new Float(halfArrowWidth * java.lang.Math.cos(angleRad - java.lang.Math.PI / 4.0))
                .intValue();

    g.setPen(new Pen(colBorder, Pen.SOLID, 1));
    g.setBrush(new Brush(colLeft, Brush.SOLID));
    g.fillPolygon(pointsX, pointsY, 3);

    pointsX[2] =
        centerX
            + new Float(halfArrowWidth * java.lang.Math.sin(angleRad + java.lang.Math.PI / 4.0))
                .intValue();
    pointsY[2] =
        centerY
            - new Float(halfArrowWidth * java.lang.Math.cos(angleRad + java.lang.Math.PI / 4.0))
                .intValue();

    g.setBrush(new Brush(colRight, Brush.SOLID));
    g.fillPolygon(pointsX, pointsY, 3);

    if (bDrawText) {
      int tempFontSize = new Float(scale * mainFont.getSize()).intValue();
      Font tempFont = new Font(mainFont.getName(), Font.BOLD, tempFontSize);
      g.setFont(tempFont);
      FontMetrics tempFm = g.getFontMetrics(tempFont);
      float stringHeight = tempFm.getHeight();
      float stringWidth = tempFm.getTextWidth(strDir);
      float stringGap =
          (float) java.lang.Math.sqrt(stringHeight * stringHeight + stringWidth * stringWidth);

      float stringPosition = arrowLength - stringGap / 2.0f;
      g.setColor(colText);
      g.drawText(
          strDir,
          centerX
              + new Float(stringPosition * java.lang.Math.sin(angleRadText) - stringWidth / 2.0f)
                  .intValue(),
          centerY
              - new Float(stringPosition * java.lang.Math.cos(angleRadText) + stringHeight / 2.0f)
                  .intValue());

      g.setFont(mainFont);
    }
  }