<?php

namespace Drupal\automated_crop\Plugin\AutomatedCrop;

use Drupal\automated_crop\AbstractAutomatedCrop;

/**
 * Provides a default automatic crop based on a 
 * Crop Type Entity provided by the crop module.
 *
 * @AutomatedCrop(
 *   id = "automated_crop_default",
 *   label = @Translation("Automated crop"),
 *   description = @Translation("The default strategy for automatic crop."),
 * )
 */
final class AutomatedCropDefault extends AbstractAutomatedCrop {

  /**
   * {@inheritdoc}
   */
  public function calculateCropBoxCoordinates() {
    $this->cropBox['x'] = ($this->originalImageSizes['width'] / 2) - ($this->cropBox['width'] / 2);
    $this->cropBox['y'] = ($this->originalImageSizes['height'] / 2) - ($this->cropBox['height'] / 2);

    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function calculateCropBoxSize() {
    $this->automatedCropBoxCalculation();

    $width = $this->cropBox['width'];
    $height = $this->cropBox['height'];

    $this->setCropBoxSize($width, $height);

    return $this;
  }

  /**
   * Calculate size automatically based on origin image width and height.
   *
   * This method assumes you want to crop the height of your image 
   * based on the Crop Type entity provided by the Crop module. 
   * If no aspect ratio settings are entered in the crop type entity 
   * settings, it will assume that you want to maintain the original 
   * image's aspect ratio.
   *
   * This method also contains a system that avoids exceeding
   * the maximum sizes of the crop area.
   */
  protected function automatedCropBoxCalculation() {
    $width = $this->originalImageSizes['width'];
    $height = $this->originalImageSizes['height'];
    $aspectWidth = $width;
    $aspectHeight = $height;
    $aspectRatio = $aspectWidth / $aspectHeight;

    if (!empty($this->cropBox['aspect_ratio'])) {
      // If user input is formatted, ex: 16:9.
      if (is_string($this->cropBox['aspect_ratio']) && strpos($this->cropBox['aspect_ratio'], ':') !== FALSE) {
        $measures = explode(':', $this->cropBox['aspect_ratio']);
        $aspectRatio = $measures[0] / $measures[1];
      }

      // If user input is numeric, ex: 1.777.
      elseif (is_numeric($this->cropBox['aspect_ratio'])) {
        $aspectRatio = (float) $this->cropBox['aspect_ratio'];
      }
    }

    // Vertical.
    if ($aspectRatio < 1) {
      $newWidth = min($height * $aspectRatio, $width);
      $newHeight = $newWidth / $aspectRatio;
    }
    // Horizontal.
    else {
      $newHeight = min($width / $aspectRatio, $height);
      $newWidth = $newHeight * $aspectRatio;
    }

    $this->cropBox['width'] = (int) $newWidth;
    $this->cropBox['height'] = (int) $newHeight;
  }

}
