#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#include "Element.h"
#include "Problem.h"

static const size_t MAX_SIZE_DISPLAY = 100;
static const size_t LENGTH_MAJ = 10;
static const size_t LENGTH_PART = 10;
static const size_t NB_UNIQUE = 4;

static void printSequence(const Element* const * sequence, size_t length)
{
    printf("[");
    for (size_t i = 0; i < length ; i++)
        printf("%d, ", getCode(sequence[i]));
    printf("]\n");
}

int main()
{

    srand(time(NULL));//Use an integer seed to get a fix sequence

    //Majority element
    Element** majSeq = createMajoritySequence(LENGTH_MAJ);
    if (!majSeq)
    {
        fprintf(stderr, "An error occurred while allocating majority sequence\n");
        return -1;
    }

    if (LENGTH_MAJ < MAX_SIZE_DISPLAY)
    {
        printf("Marjority Sequence:\n");
        printSequence((const Element* const *)majSeq, LENGTH_MAJ);
    }

    const Element* major = getMajElDC((const Element* const *)majSeq, LENGTH_MAJ);
    if (!major)
        printf("There is no majority element\n");
    else
        printf("The majority element is '%d'\n", getCode(major));

    deleteSequence(majSeq, LENGTH_MAJ);


    //Optimal partition
    Element** partSeq = createFewUniquesSequence(NB_UNIQUE, LENGTH_PART);
    if (!majSeq)
    {
        fprintf(stderr, "An error occurred while allocating partition sequence\n");
        return -1;
    }

    if (LENGTH_PART < MAX_SIZE_DISPLAY)
    {
        printf("Parition Sequence:\n");
        printSequence((const Element* const *)partSeq, LENGTH_PART);
    }

    size_t nbSubseq = 0;
    size_t* indices = NULL;

    int status = getMinCutDP((const Element* const *)partSeq, LENGTH_PART, &nbSubseq, &indices);
    if (status != 0 || nbSubseq == 0 || indices == NULL)
    {
        fprintf(stderr, "An error occurred while computing the optimal partition\n");
        deleteSequence(partSeq, LENGTH_PART);
        return -1;
    }
    printf("There are %zu subsequences\n", nbSubseq);
    if (LENGTH_PART < MAX_SIZE_DISPLAY)
    {
        printf("The partition is:\n");
        size_t start;
        size_t end;
        size_t sublength;
        for (size_t i = 0; i < nbSubseq; i++)
        {
            start = indices[i];
            end = (i+1 < nbSubseq)? indices[i+1]-1: LENGTH_PART-1;
            sublength = end-start+1;
            printSequence((const Element* const *)partSeq+start, sublength);
        }
    }

    free(indices);
    deleteSequence(partSeq, LENGTH_PART);

    return 0;
}
