content: package com.alexstyl.specialdates.upcoming.widget.list;
  
  import android.graphics.Bitmap;
  import android.graphics.BitmapShader;
  import android.graphics.Canvas;
  import android.graphics.Color;
  import android.graphics.Paint;
  import android.graphics.Typeface;
  import android.support.annotation.Px;
  
  import com.alexstyl.resources.Colors;
  import com.alexstyl.specialdates.Optional;
  import com.alexstyl.specialdates.R;
  import com.alexstyl.specialdates.contact.Contact;
  import com.alexstyl.specialdates.contact.DisplayName;
  import com.alexstyl.specialdates.images.ImageLoader;
  
  import static android.graphics.Shader.TileMode.CLAMP;
  
  final class CircularAvatarFactory {
  
      private static final String SMILEY_FACE = ":)";
      private static final Typeface ROBOTO_LIGHT = Typeface.create("sans-serif-light", Typeface.NORMAL);
  
      private final ImageLoader imageLoader;
      private final Colors colors;
  
      CircularAvatarFactory(ImageLoader imageLoader, Colors colors) {
          this.imageLoader = imageLoader;
          this.colors = colors;
      }
  
      Optional<Bitmap> circularAvatarFor(Contact contact, @Px int targetSize) {
          Optional<Bitmap> bitmapOptional = imageLoader
                  .load(contact.getImagePath())
                  .withSize(targetSize, targetSize)
                  .synchronously();
          if (!bitmapOptional.isPresent()) {
              return Optional.Companion.absent();
          }
  
          Bitmap avatar = bitmapOptional.get();
          Bitmap circleBitmap = Bitmap.createBitmap(avatar.getWidth(), avatar.getHeight(), Bitmap.Config.ARGB_8888);
          Canvas canvas = new Canvas(circleBitmap);
          Paint paint = createPaintFrom(avatar);
  
          canvas.drawCircle(
                  circleBitmap.getWidth() / 2.0f,
                  circleBitmap.getHeight() / 2.0f,
                  circleBitmap.getWidth() / 2.0f,
                  paint
          );
          return new Optional<>(circleBitmap);
      }
  
      private Paint createPaintFrom(Bitmap avatar) {
          Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
          BitmapShader shader = new BitmapShader(avatar, CLAMP, CLAMP);
          paint.setShader(shader);
          return paint;
      }
  
      Bitmap createLetterAvatarFor(DisplayName displayName, @Px int viewSize, @Px int letterSize) {
          Bitmap drawingBitmap = Bitmap.createBitmap(viewSize, viewSize, Bitmap.Config.ARGB_8888);
          Canvas canvas = new Canvas(drawingBitmap);
  
          Paint backgroundPaint = createBackgroundPaint();
          float radius = canvas.getWidth() / 2.0f;
          canvas.drawCircle(radius, radius, radius, backgroundPaint);
  
          Paint textPaint = createTextPaint(letterSize);
          int xPos = canvas.getWidth() / 2;
          int yPos = (canvas.getHeight() / 2 - ((((int) (textPaint.descent() + textPaint.ascent()))) / 2));
          canvas.drawText(firstLetterOf(displayName), xPos, yPos, textPaint);
          return drawingBitmap;
      }
  
      private Paint createBackgroundPaint() {
          Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
          backgroundPaint.setColor(colors.getDailyReminderColor());
          return backgroundPaint;
      }
  
      private static Paint createTextPaint(@Px int letterSize) {
          Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
          paint.setColor(Color.WHITE);
          paint.setTextSize(letterSize);
          paint.setTypeface(ROBOTO_LIGHT);
          paint.setTextAlign(Paint.Align.CENTER);
          return paint;
      }
  
      private static String firstLetterOf(DisplayName displayName) {
          String rawDisplayName = displayName.toString();
          if (rawDisplayName.length() == 0) {
              return SMILEY_FACE;
          }
          return rawDisplayName.substring(0, 1).toUpperCase();
      }
  }
  