<?php

if (!function_exists('copy_and_resize_image')) {

    /**
     * @title copia y redimensionamiento de una imagen
     * @access public
     * @param string $src_file Path y Nombre de la imagen de donde se copiara
     * @param string $new_path Path donde se copiará 
     * @param string $new_file Nombre y Tipo del nuevo archivo
     * @param string $final_size Tamño final al que se redimensionará la imagen, se toma el mayor alto o ancho y se mantiene relacion de aspecto
     */
    function copy_and_resize_image($src_file, $new_path, $new_file, $final_size) {
        $src_img = image_create_from_any($src_file);
        list($x, $y) = getimagesize($src_file);
        if (validate_image_smaller_than_needed($x, $y)) {
            $dimensiones = get_new_dimensions_for_resize_image($final_size, $x, $y);
            $output_image = imagecreatetruecolor($dimensiones['x'], $dimensiones['y']);
            imagealphablending($output_image, FALSE);
            imagesavealpha($output_image, TRUE);
            $transparent_color = imagecolorallocatealpha($output_image, 0, 0, 0, 127);
            imagefill($output_image, 0, 0, $transparent_color);
            imagecopyresampled($output_image, $src_img, 0, 0, 0, 0, $dimensiones['x'], $dimensiones['y'], $x, $y);
            create_any_format_image($output_image, $new_path, $new_file);
        } else {
            create_any_format_image($src_img, $new_path, $new_file);
        }
    }

}

if (!function_exists('copy_and_convert_image_to_inner_square')) {

    /**
     * @title copia y redimensionamiento de una imagen
     * @access public
     * @param string $src_file Path y Nombre de la imagen de donde se copiara
     * @param string $new_path Path donde se copiará 
     * @param string $new_file Nombre y Tipo del nuevo archivo
     * @param string $final_size Tamño final al que se redimensionará la imagen, se considera el 'menor' entre ancho y alto
     */
    function copy_and_convert_image_to_inner_square($src_file, $new_path, $new_file, $final_size = 40) {
        $src_img = image_create_from_any($src_file);
        list($x, $y) = getimagesize($src_file);
        // horizontal rectangle
        if ($x > $y) {
            $square = $y;              // $square: square side length
            $offset_x = ($x - $y) / 2;  // x offset based on the rectangle
            $offset_y = 0;              // y offset based on the rectangle
        }
        // vertical rectangle
        elseif ($y > $x) {
            $square = $x;
            $offset_x = 0;
            $offset_y = ($y - $x) / 2;
        }
        // it's already a square
        else {
            $square = $x;
            $offset_x = $offset_y = 0;
        }
        $output_image = imagecreatetruecolor($final_size, $final_size);
        imagealphablending($output_image, FALSE);
        imagesavealpha($output_image, TRUE);
        $transparent_color = imagecolorallocatealpha($output_image, 0, 0, 0, 127);
        imagefill($output_image, 0, 0, $transparent_color);
        imagecopyresampled($output_image, $src_img, 0, 0, $offset_x, $offset_y, $final_size, $final_size, $square, $square);
        create_any_format_image($output_image, $new_path, $new_file);
    }

}

if (!function_exists('copy_and_convert_image_to_outter_square')) {

    /**
     * @title copia y redimensionamiento de una imagen
     * @access public
     * @param string $src_file Path y Nombre de la imagen de donde se copiara
     * @param string $new_path Path donde se copiará 
     * @param string $new_file Nombre y Tipo del nuevo archivo
     * @param string $final_size Tamño final al que se redimensionará la imagen, se considera el 'mayor' entre ancho y alto
     */
    function copy_and_convert_image_to_outter_square($src_file, $new_path, $new_file, $final_size = 40) {
        $src_img = image_create_from_any($src_file);
        list($x, $y) = getimagesize($src_file);
        $ratio1 = $x / $final_size;
        $ratio2 = $y / $final_size;
        if ($ratio1 > $ratio2) {
            $thumb_w = $final_size;
            $thumb_h = $y / $ratio1;
        } else {
            $thumb_h = $final_size;
            $thumb_w = $x / $ratio2;
        }
        // we create a new image with the new dimmensions
        $smaller_image_with_proportions = imagecreatetruecolor($thumb_w, $thumb_h);
        imagealphablending($smaller_image_with_proportions, FALSE);
        imagesavealpha($smaller_image_with_proportions, TRUE);
        $transparent_color = imagecolorallocatealpha($smaller_image_with_proportions, 0, 0, 0, 127);
        imagefill($smaller_image_with_proportions, 0, 0, $transparent_color);
        // resize the big image to the new created one
        imagecopyresampled($smaller_image_with_proportions, $src_img, 0, 0, 0, 0, $thumb_w, $thumb_h, $x, $y);
//        create_any_format_image($smaller_image_with_proportions, $new_file);
        // *** End of Step one ***
        // Step Two (this is new): "Copy and Paste" the $smaller_image_with_proportions in the center of a white image of the desired square dimensions
        // Create image of $square_dimensions x $square_dimensions in white color (white background)
        $output_image = imagecreatetruecolor($final_size, $final_size);
        imagealphablending($output_image, FALSE);
        imagesavealpha($output_image, TRUE);
        $transparent_color = imagecolorallocatealpha($output_image, 0, 0, 0, 127);
        imagefill($output_image, 0, 0, $transparent_color);
        // need to center the small image in the squared new white image
        if ($thumb_w > $thumb_h) {
            // more width than height we have to center height
            $dst_x = 0;
            $dst_y = ($final_size - $thumb_h) / 2;
        } elseif ($thumb_h > $thumb_w) {
            // more height than width we have to center width
            $dst_x = ($final_size - $thumb_w) / 2;
            $dst_y = 0;
        } else {
            $dst_x = 0;
            $dst_y = 0;
        }
        $src_x = 0; // we copy the src image complete
        $src_y = 0; // we copy the src image complete
        $src_w = $thumb_w; // we copy the src image complete
        $src_h = $thumb_h; // we copy the src image complete
        imagecopyresampled($output_image, $smaller_image_with_proportions, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $src_w, $src_h);
        create_any_format_image($output_image, $new_path, $new_file);
    }

}

if (!function_exists('image_create_from_any')) {

    function image_create_from_any($src_file) {
        if (!file_exists($src_file)) {
            throw new Exception("ERROR: Archivo inexistente (" . $src_file . "), por favor contacte a soporte técnico");
        }
        $type = exif_imagetype($src_file);
        $allowedTypes = array(
            1, // [] gif
            2, // [] jpg
            3, // [] png
            6   // [] bmp
        );
        if (!in_array($type, $allowedTypes)) {
            throw new Exception("Error: tipo de archivo no soportado, favor de subir un archivo soportado por el sistema");
        }
        switch ($type) {
            case 1 :
                if (!$new_image = imageCreateFromGif($src_file)) {
                    throw new Exception("Error: la imagen no puede ser procesada");
                }
                break;
            case 2 :
                if (!$new_image = imageCreateFromJpeg($src_file)) {
                    throw new Exception("Error: la imagen no puede ser procesada");
                }
                break;
            case 3 :
                if (!$new_image = imageCreateFromPng($src_file)) {
                    throw new Exception("Error: la imagen no puede ser procesada");
                }
                break;
            case 6 :
                if (!$new_image = imageCreateFromBmp($src_file)) {
                    throw new Exception("Error: la imagen no puede ser procesada");
                }
                break;
        }
        return $new_image;
    }

}

if (!function_exists('validate_image_smaller_than_needed')) {

    function validate_image_smaller_than_needed($x, $y) {
        if ($x <= 200 && $y <= 200) {
            return FALSE;
        }
        return TRUE;
    }

}

if (!function_exists('get_new_dimensions_for_resize_image')) {

    function get_new_dimensions_for_resize_image($endSize, $x, $y) {
        $dimensions = array();
        // horizontal rectangle
        if ($x > $y) {
            $resize_porcentage = $endSize / $x;
            $dimensions['x'] = $x * $resize_porcentage;
            $dimensions['y'] = $y * $resize_porcentage;
        }
        // vertical rectangle
        elseif ($y > $x) {
            $resize_porcentage = $endSize / $y;
            $dimensions['x'] = $x * $resize_porcentage;
            $dimensions['y'] = $y * $resize_porcentage;
        }
        // it's already a square
        else {
            $dimensions['x'] = $endSize;
            $dimensions['y'] = $endSize;
        }
        return $dimensions;
    }

}

if (!function_exists('create_any_format_image')) {

    function create_any_format_image($output_image, $new_path, $new_file) {
        if (!file_exists($new_path)) {
            throw new Exception("ERROR: Archivo inexistente (" . $new_path . "), por favor contacte a soporte técnico");
        }
        $array_file_name = explode('.', $new_file);
        $extension = end($array_file_name);
        $allowed_types = array(
            'gif', // [] gif
            'jpg', // [] jpg
            'jpeg', // [] jpg
            'png', // [] png
            'bmp'   // [] bmp
        );
        if (!in_array($extension, $allowed_types)) {
            throw new Exception("Error: tipo de archivo no soportado, favor de subir un archivo soportado por el sistema");
        }
        switch ($extension) {
            case 'gif' :
                imagegif($output_image, $new_path . $new_file);
                break;
            case 'jpg' : case 'jpeg':
                imagejpeg($output_image, $new_path . $new_file);
                break;
            case 'png' :
                imagepng($output_image, $new_path . $new_file);
                break;
            case 'bmp' :
                imagebmp($output_image, $new_path . $new_file);
                break;
        }
        imagedestroy($output_image);
    }

}

if (!function_exists('save_image_from_base64')) {

    function save_image_from_base64($path, $name, $data, $allowed_types = 'jpg|gif|png') {
        $aux_allowed_types = explode('|', $allowed_types);
        if (preg_match('/^data:image\/(\w+);base64,/', $data, $type)) {
            $data1 = substr($data, strpos($data, ',') + 1);
            $type = strtolower($type[1]); // jpg, png, gif
            if ($type === 'jpeg') {
                $type = 'jpg';
            }
            if (!in_array($type, $aux_allowed_types)) {
                return array('status' => 401, 'error_message' => 'Formato de imagen invalido.');
            }
            $data2 = str_replace(' ', '+', $data1);
            $data3 = base64_decode($data2);
            if ($data3 === false) {
                return array('status' => 401, 'error_message' => 'Error al procesar la imagen.');
            }
        } else {
            return array('status' => 401, 'error_message' => 'Error al leer la imagen.');
        }
        $img = imagecreatefromstring($data3);
        imagejpeg($img, $path . $name . '.' . $type);
        return array('status' => 200, 'path' => $path, 'image_name' => $name, 'type_image' => $type);
    }

}