package com.example.imagefilterer;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.graphics.Bitmap;
import android.provider.MediaStore;
import android.view.ViewGroup;
import android.widget.Button;
import android.os.Bundle;
import android.view.View;
import android.content.Intent;
import android.net.Uri;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Scanner;
import android.app.Activity;
import android.graphics.Color;
import android.util.Log;
import android.widget.ImageView;
import android.widget.Toast;



import java.io.IOException;
import java.util.Scanner;


import android.widget.EditText;
import android.widget.TextView;

// Addition by Ian Lee
import android.graphics.drawable.BitmapDrawable;
import android.graphics.Color;


public class MainActivity extends AppCompatActivity{
    // When declaring the components we want to specify the type
    // from xml file and the corresponding string.

    //Component Tree:
    //BUTTONS
    private Button uploadimage;
    private Button uploadtext;
    private Button zeroGB;
    private Button resize;
    private Button rotate;
    private Button blur;
    private Button grayscale;
    //IMAGE VIEW
    private Button histogram;
    private ImageView dispimage;

    //TEXT VIEW
    private TextView angle;
    private TextView edit_height;
    private TextView edit_width;

    private static final int PICK_FILE_REQUEST_CODE = 1;
    private static final int READ_REQUEST_CODE = 42;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        uploadimage = (Button) findViewById(R.id.uploadimage);
        uploadtext = (Button) findViewById(R.id.uploadtext);
        resize = (Button) findViewById(R.id.resize);
        rotate = (Button) findViewById(R.id.rotate);
        dispimage = (ImageView) findViewById(R.id.dispimage);
        blur = (Button) findViewById(R.id.imageblur);
        zeroGB = (Button) findViewById(R.id.zeroGB);
        angle = (EditText) findViewById(R.id.angle);
        grayscale = (Button) findViewById(R.id.grayscale);
        edit_height = (EditText) findViewById(R.id.edit_height);
        edit_width = (EditText) findViewById(R.id.edit_width);
        histogram = (Button) findViewById(R.id.histogram);
        //histogramView = (ImageView) findViewById(R.id.histogramView);

        uploadimage.setOnClickListener(new View.OnClickListener() {
            // Logic that enables the user to click the Upload Image button to access the device storage
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                intent.setType("*/*"); //set MIME type to filter files
                startActivityForResult(Intent.createChooser(intent, "Select File"), PICK_FILE_REQUEST_CODE);
            }
        });


        resize.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //openDialog();
                int newWidth = Integer.parseInt(edit_width.getText().toString());
                int newHeight = Integer.parseInt(edit_height.getText().toString());

                // Get the current dimensions of the image
                int currentWidth = dispimage.getWidth();
                int currentHeight = dispimage.getHeight();

                // Create a new bitmap with the desired dimensions
                Bitmap bitmap = ((BitmapDrawable) dispimage.getDrawable()).getBitmap();
                Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);

                // Update the ImageView with the resized bitmap
                dispimage.setImageBitmap(resizedBitmap);

                // Adjust the layout parameters of the ImageView to match the new dimensions
                ViewGroup.LayoutParams params = dispimage.getLayoutParams();
                params.width = newWidth;
                params.height = newHeight;
                dispimage.setLayoutParams(params);
            }
        });


        uploadtext.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Start file picker activity
                Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                intent.setType("*/*");
                startActivityForResult(intent, READ_REQUEST_CODE);

             }

        });

        rotate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
           if (angle.getText().toString().isEmpty()) {
               // Display a toast message
               Toast.makeText(MainActivity.this, "Field cannot be empty!!", Toast.LENGTH_SHORT).show();
           } else {
               // Set the rotation of the image view
               float mAngleRotate = Float.parseFloat(angle.getText().toString());
               dispimage.setRotation(mAngleRotate);
           }
            }
        });

        zeroGB.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // Zero out the green and blue components of an image
                    Bitmap originalBitmap = ((BitmapDrawable) dispimage.getDrawable()).getBitmap();
                    int width = originalBitmap.getWidth();
                    int height = originalBitmap.getHeight();
                    Bitmap recolorBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

                    int[] pixels = new int[width * height];
                    originalBitmap.getPixels(pixels, 0, width, 0, 0, width, height);

                    for (int i = 0; i < pixels.length; i++) {
                        int red = Color.red(pixels[i]);
                        int recolorPixel = Color.rgb(red, 0, 0);
                        pixels[i] = recolorPixel;
                    }

                    recolorBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
                    dispimage.setImageBitmap(recolorBitmap);
            }
        });

        blur.setOnClickListener(new View.OnClickListener() {
            // Image blur algorithm
            @Override
            public void onClick(View v) {
                Bitmap originalBitmap = ((BitmapDrawable) dispimage.getDrawable()).getBitmap();
                int width = originalBitmap.getWidth();
                int height = originalBitmap.getHeight();
                Bitmap blurredBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

                int[] pixels = new int[width * height];
                int[] blurredPixels = new int[width * height];
                originalBitmap.getPixels(pixels, 0, width, 0, 0, width, height);

                // For each pixel in the image, calculate the average color value of its neighbors
                for (int row = 0; row < height; row++) {
                    for (int col = 0; col < width; col++) {
                        int rTotal = 0, gTotal = 0, bTotal = 0, count = 0;

                        for (int rowOffset = -1; rowOffset <= 1; rowOffset++) {
                            int neighborRow = row + rowOffset;

                            if (neighborRow < 0 || neighborRow >= height) {
                                continue;
                            }

                            for (int colOffset = -1; colOffset <= 1; colOffset++) {
                                int neighborCol = col + colOffset;

                                if (neighborCol < 0 || neighborCol >= width) {
                                    continue;
                                }

                                int neighborPixelIndex = neighborRow * width + neighborCol;
                                int neighborPixel = pixels[neighborPixelIndex];
                                int r = Color.red(neighborPixel);
                                int g = Color.green(neighborPixel);
                                int b = Color.blue(neighborPixel);
                                rTotal += r;
                                gTotal += g;
                                bTotal += b;
                                count++;
                            }
                        }

                        int pixelIndex = row * width + col;
                        int pixel = pixels[pixelIndex];
                        int r = Color.red(pixel);
                        int g = Color.green(pixel);
                        int b = Color.blue(pixel);

                        int newR = (rTotal + r) / (count + 1);
                        int newG = (gTotal + g) / (count + 1);
                        int newB = (bTotal + b) / (count + 1);

                        blurredPixels[pixelIndex] = Color.rgb(newR, newG, newB);
                    }
                }

                blurredBitmap.setPixels(blurredPixels, 0, width, 0, 0, width, height);
                dispimage.setImageBitmap(blurredBitmap);
            }
        });

        grayscale.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Bitmap originalBitmap = ((BitmapDrawable) dispimage.getDrawable()).getBitmap();
                Bitmap grayscaleBitmap = Bitmap.createBitmap(originalBitmap.getWidth(), originalBitmap.getHeight(), Bitmap.Config.ARGB_8888);

                for (int x = 0; x < originalBitmap.getWidth(); x++) {
                    for (int y = 0; y < originalBitmap.getHeight(); y++) {
                        int pixel = originalBitmap.getPixel(x, y);
                        int red = Color.red(pixel);
                        int green = Color.green(pixel);
                        int blue = Color.blue(pixel);

                        // Calculate the average of the RGB values to get the grayscale value}
                        int gray = (red + green + blue) / 3;

                        grayscaleBitmap.setPixel(x, y, Color.rgb(gray, gray, gray));
                    }
                }

                dispimage.setImageBitmap(grayscaleBitmap);

            }

        });

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Logic that displays the user uploaded image onto the ImageView template
        if (requestCode == PICK_FILE_REQUEST_CODE && resultCode == RESULT_OK) {
            Uri uri = data.getData();
            try {
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
                dispimage.setImageBitmap(bitmap);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else if (requestCode == READ_REQUEST_CODE && resultCode == RESULT_OK) {
            Uri uri = null;
            int count = 0;
            if (data != null) {
                uri = data.getData();
                Log.i("TAG", "Uri: " + uri.toString());
            }

            if (uri != null) {
                try {
                    InputStream inputStream = getContentResolver().openInputStream(uri);
                    BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
                    String line = br.readLine();

                    try {
                        int width = Integer.parseInt(line.trim());
                        int height = Integer.parseInt(br.readLine().trim());

                        br.mark(1000);

                        if (width <= 0 || height <= 0) {
                            count += 1; // one error
                        }

                        int expectedNumLines = width * height;
                        int currentNumLines = 0;
                        while ((line = br.readLine()) != null) {
                            currentNumLines += 1;
                        }
                        if (expectedNumLines != currentNumLines) {
                            count += 1; //one error
                        }

                        br.reset();

                        while ((line = br.readLine()) != null) {
                            String[] tokens = line.split("\\s+");
                            if (tokens.length != 3) {
                                count += 1; //one error
                            }
                            for (String token : tokens) {
                                int value = Integer.parseInt(token);
                                if (value < 0 || value > 100) {
                                    count += 1; // one error
                                }
                            }
                        }
                    } catch (NumberFormatException e) {
                        Toast.makeText(MainActivity.this, "Wrong file format", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    br.close();
                    inputStream.close();
                } catch (IOException e) {
                    Log.e("MainActivity", "Unable to read file", e);
                }
            }

            if (count == 0) {
                try {
                    // read the image data from the file
                    Scanner scanner = new Scanner(getContentResolver().openInputStream(uri));

                    // read the dimensions of the image
                    int width = scanner.nextInt();
                    int height = scanner.nextInt();

                    // create a Bitmap to store the pixel data
                    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

                    // read in the pixel data
                    for (int y = 0; y < height; y++) {
                        for (int x = 0; x < width; x++) {
                            int r = scanner.nextInt() * 255 / 100;
                            int g = scanner.nextInt() * 255 / 100;
                            int b = scanner.nextInt() * 255 / 100;
                            int rgb = Color.rgb(r, g, b);
                            bitmap.setPixel(x, y, rgb);
                        }
                    }

                    ImageView dispimage = findViewById(R.id.dispimage);
                    dispimage.setImageBitmap(bitmap);

                } catch (IOException e) {
                    Log.e("TAG", "Error reading file", e);
                }
            } else {
            }
        }
    }
}
