
// imageEffects provides functions to perform image effects

package imageEffects

import "seekia/imported/goeffects"

import "seekia/internal/imagery"
import "seekia/internal/helpers"

import "image"
import "image/draw"
import "errors"


func ApplyCartoonEffect(inputImage image.Image, effectStrength int) (image.Image, error){

	if (inputImage == nil){
		return nil, errors.New("ApplyCartoonEffect called with nil inputImage")
	}

	if (effectStrength <= 0){
		return inputImage, nil
	}
	if (effectStrength > 100) {
		effectStrength = 100
	}
	
	result, err := goeffects.ApplyCartoonEffect(inputImage, effectStrength)

	return result, err
}

func ApplyPencilEffect(inputImage image.Image, effectStrength int) (image.Image, error){

	if (inputImage == nil){
		return nil, errors.New("ApplyPencilEffect called with nil inputImage")
	}

	if (effectStrength <= 0){
		return inputImage, nil
	}
	if (effectStrength > 100) {
		effectStrength = 100	
	}
	
	result, err := goeffects.ApplyPencilEffect(inputImage, effectStrength)

	return result, err
}

func ApplyOilPaintingEffect(inputImage image.Image, effectStrength int) (image.Image, error){

	if (inputImage == nil){
		return nil, errors.New("ApplyOilPaintingEffect called with nil inputImage")
	}

	if (effectStrength <= 0){
		return inputImage, nil
	}
	if (effectStrength > 100) {
		effectStrength = 100	
	}
	
	result, err := goeffects.ApplyOilPaintingEffect(inputImage, effectStrength)

	return result, err
}

func ApplyWireframeEffect(inputImage image.Image, effectStrength int) (image.Image, error){

	if (inputImage == nil){
		return nil, errors.New("ApplyWireframeEffect called with nil inputImage")
	}

	if (effectStrength <= 0){
		return inputImage, nil
	}
	if (effectStrength > 100) {
		effectStrength = 100	
	}
	
	result, err := goeffects.ApplyWireframeEffect(inputImage, effectStrength, false)

	return result, err
}

func ApplyStrokeEffect(inputImage image.Image, effectStrength int) (image.Image, error){

	if (inputImage == nil){
		return nil, errors.New("ApplyStrokeEffect called with nil inputImage")
	}

	if (effectStrength <= 0){
		return inputImage, nil
	}
	if (effectStrength > 100) {
		effectStrength = 100	
	}
	
	result, err := goeffects.ApplyWireframeEffect(inputImage, effectStrength, true)

	return result, err
}

func GetImageWithEmojiOverlay(inputImage image.Image, emojiImage image.Image, emojiScale int, xAxisPercentage int, yAxisPercentage int)(image.Image, error){

	if (inputImage == nil) {
		return nil, errors.New("GetImageWithEmojiOverlay called with nil inputImage.")
	}
	if (emojiImage == nil) {
		return nil, errors.New("GetImageWithEmojiOverlay called with nil emojiImage.")
	}

	newImageRGBA := image.NewRGBA(inputImage.Bounds())
	draw.Draw(newImageRGBA, inputImage.Bounds(), inputImage, image.Point{}, draw.Over)

	imageWidth, imageHeight, err := imagery.GetImageWidthAndHeightPixels(inputImage)
	if (err != nil) { return nil, err }

	imageLongerSideLength := max(imageWidth, imageHeight)

	// This is the length of the longest side of the emoji we will draw
	emojiLongerSideMaximumLength, err := helpers.ScaleIntProportionally(true, emojiScale, 0, 100, 1, imageLongerSideLength)
	if (err != nil) { return nil, err }

	newEmoji, err := imagery.ResizeGolangImage(emojiImage, emojiLongerSideMaximumLength)
	if (err != nil) { return nil, err }

	// Now we get the X and Y Coordinate point for where we will draw the emoji
	// We first find the center coordinate of the emoji we are drawing

	emojiCenterXCoordinate, err := helpers.ScaleIntProportionally(true, xAxisPercentage, 0, 100, 0, imageWidth)
	if (err != nil) { return nil, err }

	emojiCenterYCoordinate, err := helpers.ScaleIntProportionally(false, yAxisPercentage, 0, 100, 0, imageHeight)
	if (err != nil) { return nil, err }

	emojiWidth, emojiHeight, err := imagery.GetImageWidthAndHeightPixels(newEmoji)
	if (err != nil) { return nil, err }

	// Now we find the coordinates of the top left corner of the emoji we are drawing.

	pointXCoordinate := -(emojiCenterXCoordinate - (emojiWidth/2))
	pointYCoordinate := -(emojiCenterYCoordinate - (emojiHeight/2))
	
	emojiDrawPoint := image.Point{ X : pointXCoordinate, Y : pointYCoordinate }
 
	draw.Draw(newImageRGBA, inputImage.Bounds(), newEmoji, emojiDrawPoint, draw.Over)

	return newImageRGBA, nil
}




