// Built by Peter A Noble  Dec 14, 2023 Email: panoble2017@gmail.com
// Copyright 2023

#include <fstream>
#include <string>
#include <iostream>
#include <math.h>
#include <cstdlib>
#include <float.h>
#include <complex>
#include <iomanip>
#include <cmath>
#include <vector>
#include <algorithm>
#include <ctime>

// g++ add_shuffle.cpp -o add_shuffle
// ./add_shuffle 28 84 0.0 image_9994_label_1.txt shuf_image_9994_label_1.txt
// ./add_shuffle 28 84 0.0 9994.txt shuf_9994.txt
//9994


void shufflePixels(int** arr, int width, int height, double percentage) {
    srand(static_cast<unsigned>(time(0))); // Seed for randomization

    int numPixelsToShuffle = static_cast<int>(width * height * percentage / 100.0);

    // Flatten the 2D array into a 1D vector for easier shuffling
    std::vector<int> flattenedArray;
    for (int y = 0; y < height; ++y) {
        for (int x = 0; x < width; ++x) {
            flattenedArray.push_back(arr[x][y]);
        }
    }

    // Shuffle a portion of the vector using Fisher-Yates algorithm
    for (int i = 0; i < numPixelsToShuffle; ++i) {
        int randomIndex = i + rand() % (flattenedArray.size() - i);
        std::swap(flattenedArray[i], flattenedArray[randomIndex]);
    }

    // Update the 2D array with the shuffled values
    int index = 0;
    for (int y = 0; y < height; ++y) {
        for (int x = 0; x < width; ++x) {
            arr[x][y] = flattenedArray[index++];
        }
    }
}

int main(int argc, char* const argv[]) {
    int height = atoi(argv[1]);
    int width = atoi(argv[2]);
    double shufflePercentage = atof(argv[3]);
    std::ifstream in(argv[4]);         //4_array.txt
    std::ofstream out(argv[5]);        //out.txt

    int** myArray = new int*[width];
    for (int i = 0; i < width; ++i) {
        myArray[i] = new int[height];
    }

    while (!in.eof()) {
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                in >> myArray[x][y];
            }
        }
    }

    shufflePixels(myArray, width, height, shufflePercentage);

    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            out << myArray[x][y] << "\t";
        }
        out << "\n";
    }

    for (int i = 0; i < width; ++i) {
        delete[] myArray[i];
    }
    delete[] myArray;

    return 0;
}