/** @brief update helper function for the polaroid bg layer */
  private void updatePolaroidDrawable(Rect bounds) {
    PDEColor highColor;
    PDEColor lowColor;
    float red, green, blue;
    Rect frameRect = new Rect(0, 0, bounds.width(), bounds.height());

    mElementCornerRadius = bounds.width() * 0.07f;
    // update Frame
    mElementPolaroidDrawable.setBounds(frameRect);
    mElementPolaroidDrawable.setElementCornerRadius(mElementCornerRadius);
    mElementPolaroidDrawable.setElementBorderColor(mElementPolaroidFrameColor);
    // todo: this border stuff does not work properly!!! So we take a workaround.
    // mElementPolaroidDrawable.setElementBorderWidth(polaroidRelativeValue(2.5f));
    int border = Math.round(polaroidRelativeValue(2.5f));
    mElementGradientDrawable.setBounds(
        frameRect.left + border,
        frameRect.top + border,
        frameRect.right - border,
        frameRect.bottom - border);

    red = mElementPolaroidFrameColor.getRed();
    blue = mElementPolaroidFrameColor.getBlue();
    green = mElementPolaroidFrameColor.getGreen();

    highColor = new PDEColor(red, green, blue, 0.0f);
    lowColor = new PDEColor(red - 0.33f, green - 0.33f, blue - 0.33f, 0.75f);
    mElementGradientDrawable.setElementBackgroundGradientColors(highColor, highColor, lowColor);
    mElementGradientDrawable.setElementGradientDistributionPositions(0.0f, 0.85f, 1.0f);

    // set other layer data
    mElementPolaroidDrawable.setElementBackgroundColor(mElementPolaroidFrameColor);
    mElementGradientDrawable.setElementCornerRadius(mElementCornerRadius);
    mElementGradientDrawable.setElementBorderColor(PDEColor.valueOf("DTTransparentBlack"));
  }
  // initialization
  public PDEDrawablePolaroidFrame(Drawable drawable) {
    mElementImageDrawable = new PDEDrawableIconImage(drawable);
    mElementPolaroidFrameColor = PDEColor.valueOf("DTWhite");

    // init sublayers
    initLayers();

    mElementPolaroidDrawable.setElementBackgroundColor(PDEColor.valueOf("DTTransparentBlack"));
  }
  /** @brief polaroid color setting function */
  public void setElementPolaroidFrameColor(PDEColor color) {
    float red, green, blue, alpha, red2, green2, blue2, alpha2;

    // validation
    if (color == null) return;

    red = color.getRed();
    green = color.getGreen();
    blue = color.getBlue();
    alpha = color.getAlpha();
    red2 = mElementPolaroidFrameColor.getRed();
    green2 = mElementPolaroidFrameColor.getGreen();
    blue2 = mElementPolaroidFrameColor.getBlue();
    alpha2 = mElementPolaroidFrameColor.getAlpha();

    // changed?
    if (red == red2 && green == green2 && blue == blue2 && alpha == alpha2) return;

    // remember new value
    mElementPolaroidFrameColor = color;
    // mElementPolaroidDrawable.setElementBackgroundColor(mElementPolaroidFrameColor);

    // update
    invalidateSelf();
  }
  /**
   * @brief internal initial helper to init needed layers. shadow is not created here, it must
   *     initialized by createShadow separately
   */
  private void initLayers() {
    // initialize polaroid frame layer
    mElementPolaroidDrawable = new PDEDrawableRoundedBox();
    mElementPolaroidDrawable.setBounds(0, 0, 0, 0);

    // create gradient layer for polaroid
    mElementGradientDrawable = new PDEDrawableRoundedGradientBox();

    // init gradient layer for image and layer it to imagelayer
    mElementImageGradientDrawable = new PDEDrawableRoundedGradientBox();

    // create inner shadow for image
    mElementInnerShadowDrawable = new PDEDrawableShapedInnerShadow();
    mElementInnerShadowDrawable.setBounds(0, 0, 0, 0);
    //        mElementInnerShadowDrawable.setElementShapeColor(PDEColor.valueOf("DTBlack"));
    mElementInnerShadowDrawable.setElementShapeColor(PDEColor.valueOf("Black20Alpha"));
    mElementInnerShadowDrawable.setElementLightIncidenceOffset(new PointF(0.0f, 0.0f));
    //        mElementInnerShadowDrawable.setElementShapeOpacity(0.2f);

    // set shadow to null, create it on request
    mElementShadowDrawable = null;

    // hang in main layers
    addLayer(mElementPolaroidDrawable);
    addLayer(mElementGradientDrawable);
    addLayer(mElementImageDrawable);
    addLayer(mElementImageGradientDrawable);
    addLayer(mElementInnerShadowDrawable);
  }
  /** @brief update function for the image layer (image self, image gradient, image inner-shadow) */
  private void updateElementImageDrawable(Rect bounds) {
    PDEColor highColor, mainColor;
    PDEColor lowColor;
    //        float placeHolderFrameDistance;
    Rect imgBounds;

    // int
    //        placeHolderFrameDistance = (bounds.width() - polaroidRelativeValue(176.5f) )/2.0f +
    // Math.round(polaroidRelativeValue(2.5f));
    //        Rect frameRect = new Rect((int)placeHolderFrameDistance,
    // (int)placeHolderFrameDistance,
    //                                  (int)placeHolderFrameDistance +
    // (int)polaroidRelativeValue(176.5f),
    //                                  (int)placeHolderFrameDistance +
    // (int)polaroidRelativeValue(176.5f));
    int border = Math.round(polaroidRelativeValue(2.5f));
    //        Rect frameRect = new Rect(bounds.left + border,bounds.top + border,bounds.right -
    // border,
    //                                  bounds.bottom - border);

    Rect frameRect = new Rect(0, 0, bounds.width(), bounds.height());
    // mElementImageDrawable.enableAspectRatio(false);
    //        mElementImageDrawable.setBounds(frameRect.left + border, frameRect.top + border,
    // frameRect.right - 2 * border,
    //                                        frameRect.right - border);

    mElementImageDrawable.setLayoutOffset(frameRect.left + 2 * border, frameRect.top + 2 * border);
    mElementImageDrawable.setLayoutWidth(frameRect.width() - 4 * border);

    Path clipPath;
    clipPath = new Path();
    float radius = mElementPolaroidDrawable.getElementCornerRadius() - border / 2.0f;
    // calculate clip path
    //        clipPath.addRoundRect(new RectF(mElementImageDrawable.getBounds().left /*+ border*/,
    //                                        mElementImageDrawable.getBounds().top /*+ border*/,
    //                                        mElementImageDrawable.getBounds().right,
    //                                        mElementImageDrawable.getBounds().bottom),radius,
    // radius,
    //                Path.Direction.CW);

    clipPath.addRoundRect(
        new RectF(
            0.5f /*+ border*/,
            0.5f /*+ border*/,
            mElementImageDrawable.getBounds().width() - 0.5f,
            mElementImageDrawable.getBounds().height() - 0.5f),
        radius,
        radius,
        Path.Direction.CW);

    clipPath.close();
    //        mElementImageDrawable.setElementClipPath(clipPath,true);
    mElementImageDrawable.setElementClipPath(clipPath);

    // Add some gradient to the image view.
    highColor = new PDEColor(1.0f, 1.0f, 1.0f, 0.5f);
    mainColor = new PDEColor(0.5f, 0.5f, 0.5f, 0.25f);
    lowColor = new PDEColor(0.0f, 0.0f, 0.0f, 0.0f);

    //        highColor = new PDEColor(1.0f,0.0f,0.0f,0.5f);
    //        mainColor = new PDEColor(1.0f,0.0f,0.0f,0.5f);
    //        lowColor = new PDEColor(1.0f,0.0f,0.0f,0.5f);

    imgBounds = mElementImageDrawable.getBounds();
    mElementImageGradientDrawable.setLayoutRect(
        new Rect(imgBounds.left - 1, imgBounds.top - 1, imgBounds.right + 1, imgBounds.bottom + 1));

    mElementImageGradientDrawable.setElementBorderColor(PDEColor.valueOf("DTTransparentBlack"));
    mElementImageGradientDrawable.setElementCornerRadius(radius);
    mElementImageGradientDrawable.setElementBackgroundGradientColors(
        highColor, mainColor, lowColor);

    // set inner shadow on image
    mElementInnerShadowDrawable.setElementBlurRadius(polaroidRelativeValue(8.0f));
    /*        RectF layoutRect = new RectF(mElementImageDrawable.getBounds().left, mElementImageDrawable.getBounds().top,
    mElementImageDrawable.getBounds().right,
    mElementImageDrawable.getBounds().bottom);*/
    mElementInnerShadowDrawable.setLayoutRect(mElementImageGradientDrawable.getBounds());
    mElementInnerShadowDrawable.setElementShapeRoundedRect(radius);
  }