/*

    Brisanje redova i kolona matrice sa menijem

*/


#include <stdio.h>
#include <stdlib.h> // zbog exit()

#define MAX_SIZE 100


// Prikazuje matricu M[][] koja ima r redova i k kolona
void prikazi_matricu( char *tekst, int M[][MAX_SIZE], int r, int k )
{
    int i, j;

    printf("\n%s\n\n",tekst);

    for(i=0;i<r;i++) {    // Stampamo matricu M[][]
        for(j=0;j<k;j++)
            printf(" %4d",M[i][j]);

        printf("\n\n");   // novi red matrice
    }
}


// Formira matricu M[][] koja ima r redova i k kolona
// Elementi su redni brojevi.
void formiraj_matricu( int M[][MAX_SIZE], int r, int k )
{
    int i, j;

    for(i=0;i<r;i++)
        for(j=0;j<k;j++)
            M[i][j] = i*k + j+1;
}


// Prikazuje matricu M bez reda KojiRed. Ne menja matricu M.
void prikaz_matrice_bez_reda( int M[][MAX_SIZE], int r, int k, int KojiRed )
{
    int i,j;

    for(i=0;i<r;i++){
        for(j=0;j<k;j++){
            if(i != KojiRed-1)
                printf(" %4d",M[i][j]);
        }
        if(i != KojiRed-1)
            printf("\n\n");
    }
}


// Prikazuje matricu M bez kolone KojaKolona. Ne menja matricu M.
void prikaz_matrice_bez_kolone( int M[][MAX_SIZE], int r, int k, int KojaKolona )
{
    int i,j;

    for(i=0;i<r;i++){
        for(j=0;j<k;j++){
            if( j != KojaKolona-1 )
                printf(" %4d",M[i][j]);
        }
        if( j != KojaKolona-1 )
            printf("\n\n");
    }
    printf("\n");
}


// Prikazuje matricu M bez glavne dijagonale. Ne menja matricu M.
// Prikazana matrica ima isti broj redova r, broj kolona je za 1 manji.
void prikazi_matricu_bez_glavne_dijagonale( int M[][MAX_SIZE], int r, int k )
{
    int i, j;

    printf("\n");

    for(i=0;i<r;i++){
        for(j=0;j<k;j++)
            if( i != j )   // ako to nije element glavne dijagonale matrice M
                printf(" %4d",M[i][j]);

        printf("\n\n");     // novi red matrice M
    }
}


// Prikazuje matricu M bez sporedne dijagonale. Ne menja matricu M.
// Prikazana matrica ima isti broj redova r, broj kolona je za 1 manji.
void prikazi_matricu_bez_sporedne_dijagonale( int M[][MAX_SIZE], int r, int k )
{
    int i, j;

    printf("\n");

    for(i=0;i<r;i++){
        for(j=0;j<k;j++)
            // trebalo bi i+j != n-1, ovako vazi i za pravougaone matrice kod kojih je r<k
            if( i+j != r-1 )   // ako to nije element glavne dijagonale matrice M
                printf(" %4d",M[i][j]);

        printf("\n\n");     // novi red matrice M
    }
}


// Brise red KojiRed iz matrice M. Nova matrica ima za jedan manji broj redova.
void obrisi_red_matrice( int M[][MAX_SIZE], int *r, int k, int KojiRed )
{
    int i,j,ni=0,nj=0;  // ni i nj su indeksi redova i kolona nove matrice

    for(i=0;i<*r;i++)
        for(j=0;j<k;j++){
            if(i != KojiRed-1){
                 M[ni][nj]=M[i][j];

                if(nj < k)      // ako nismo dosli do kraja kolone
                    nj++;

                if(nj == k){    // ako smo dosli do kraja kolone
                    ni++;
                    nj=0;
                }
            }
        }
    (*r)--; // jer smo obrisali jedan red matrice, broj kolona k je ostao isti
}


// Brise kolonu KojaKolona iz matrice M. Nova matrica ima za jedan manji broj kolona.
void obrisi_kolonu_matrice( int M[][MAX_SIZE], int r, int *k, int KojaKolona )
{
    int i,j,nj=0;  // nj je indeks kolona nove matrice, njen indeks redova je i

    for(i=0;i<r;i++)
        for(j=0;j<*k;j++){
            if( j != KojaKolona-1 ){
                M[i][nj]=M[i][j];

                if( nj < (*k)-1 )   // ako nismo dosli do kraja reda
                    nj++;

                if( nj == (*k)-1 )  // ako smo dosli do kraja reda
                    nj=0;
            }
        }

    (*k)--; // jer smo obrisali jednu kolonu matrice, broj redova r je ostao isti
}


// Brise red red i kolonu kolona iz matrice M.
// Nova matrica ima za jedan manji broj redova i broj kolona.
void obrisi_red_r_i_kolonu_k( int M[][MAX_SIZE], int *r, int *k, int red, int kolona )
{
    int i, j, ni, nj;   // ni i nj su novi indeksi matrice sa obrisanim redom i kolonom

    red--;      // red i kolona su redni brojevi i zato ih pretvaramo u indekse matrice M
    kolona--;
    ni=0;

    for(i=0;i<*r;i++){
        nj=0;
        if( i != red ) {
            for(j=0;j<*k;j++){
                if( j != kolona ){
                    M[ni][nj++] = M[i][j];
                }
            }
            ni++;
        }
    }

    (*r)--;     // izbacili smo jedan red i smanjujemo broj redova
    (*k)--;     // izbacili smo jednu kolonu i smanjujemo broj kolona
}


// Brise glavnu dijagonalu matrice M[r][k] koja ima r redova i k kolona.
// Nova matrica bez glavne dijagonale ima isti broj redova,
// a broj kolona je za 1 manji.
void obrisi_glavnu_dijagonalu_matrice( int M[][MAX_SIZE], int r, int *k )
{
    int i, j, k1; // k1 je broj kolona matrice M sa izbacenom glavnom dijagonalom

    for(i=0;i<r;i++){

        k1=0;   // pocetna vrednost za brojac kolona nove matrice

        for(j=0;j<*k;j++)
            if( i != j )   // ako to nije element glavne dijagonale matrice M[][]
                M[i][k1++] = M[i][j];  // i povecavamo k1, broj kolona nove matrice
    }

    (*k)--;     // smanjujemo broj kolona
}


// Brise sporednu dijagonalu matrice M koja ima r redova i k kolona.
// Nova matrica bez sporedne dijagonale ima isti broj redova,
// a broj kolona je za 1 manji.
void obrisi_sporednu_dijagonalu_matrice( int M[][MAX_SIZE], int r, int *k )
{
    int i, j, k1; // k1 je broj kolona matrice M sa izbacenom glavnom dijagonalom

    for(i=0;i<r;i++){

        k1=0;   // pocetna vrednost za brojac kolona nove matrice

        for(j=0;j<*k;j++)
            // trebalo bi i+j != n-1, ovako vazi i za pravougaone matrice kod kojih je r<k
            if( i+j != r-1 )   // ako to nije element glavne dijagonale matrice M[][]
                M[i][k1++] = M[i][j];  // i povecavamo k1, broj kolona nove matrice
    }

    (*k)--;     // smanjujemo broj kolona
}


// U matrici M redovi r1 i r2 medjusobno zamenjuju mesta.
void medjusobna_zamena_mesta_dva_reda( int M[][MAX_SIZE], int r, int k, int r1, int r2 )
{
    int j, mem;

    r1--;   // redni broj reda pretvaramo u indeks
    r2--;   // redni broj reda pretvaramo u indeks

    for(j=0;j<k;j++){      // ponavljamo k puta:
        mem = M[r1][j];     // elementi dva reda r1 i r2 medjusobno zamenjuju mesta
        M[r1][j] = M[r2][j];
        M[r2][j] = mem;
    }
}


// U matrici M kolone k1 i k2 medjusobno zamenjuju mesta.
void medjusobna_zamena_mesta_dve_kolone( int M[][MAX_SIZE], int r, int k, int k1, int k2 )
{
    int i, mem;

    k1--;   // redni broj kolone pretvaramo u indeks
    k2--;   // redni broj kolone pretvaramo u indeks

    for(i=0;i<r;i++){      // ponavljamo r puta:
        mem = M[i][k1];     // elementi dva reda r1 i r2 medjusobno zamenjuju mesta
        M[i][k1] = M[i][k2];
        M[i][k2] = mem;
    }
}



int glavni_meni(void)
{
    int M[MAX_SIZE][MAX_SIZE];
    int i,r=4,k=4,KojiRed,KojaKolona; // r i k su brojevi redova i kolona matrice M
    int izbor, kraj=0;

    formiraj_matricu(M,r,k);

    while(!kraj){
        prikazi_matricu(" Matrica je: ",M,r,k);

        printf("\n \t GLAVNI MENI \n\n"     // prikazuje glavni meni
               "  1. Resetuj matricu \n"
               "  2. Prikaz matrice bez reda r \n"
               "  3. Obrisi red r matrice \n"
               "  4. Prikaz matrice bez kolone k \n"
               "  5. Obrisi kolonu k matrice \n"
               "  6. Prikaz matrice bez reda r i kolone k \n"
               "  7. Obrisi red r i kolonu k matrice \n"
               "  8. Prikazi matricu bez glavne dijagonale \n"
               "  9. Obrisi glavnu dijagonalu matrice \n"
               " 10. Prikazi matricu bez sporedne dijagonale \n"
               " 11. Obrisi sporednu dijagonalu matrice \n"
               " 12. Medjusobna zamena mesta dva reda \n"
               " 13. Medjusobna zamena mesta dve kolone \n"
               " 14. Formiraj matricu od rednih brojeva \n"
               "  0. Kraj rada \n\n"
               " \t Vas izbor je: "
               );
        scanf("%d",&izbor);

        switch(izbor){
            case 1:         // Resetuj matricu
                    formiraj_matricu(M,r,k);
                    break;
            case 2:         // Prikaz matrice bez reda
                    printf("\n Koji red ne zelis da prikazes, r = ");
                    scanf("%d", &KojiRed);
                    if ( KojiRed < 0 || KojiRed > r ) {
                        printf("\n Red %d nije ispravno unet! \n",KojiRed);
                        exit(1);
                    }
                    prikaz_matrice_bez_reda(M,r,k,KojiRed);
                    break;
            case 3:         // Obrisi red r matrice
                    printf("\n Koji red zelis da obrises, r = ");
                    scanf("%d", &KojiRed);
                    obrisi_red_matrice(M,&r,k,KojiRed);
                    break;
            case 4:         // Prikaz matrice bez kolone
                    printf("\n Koju kolonu ne zelis da prikazes, k = ");
                    scanf("%d", &KojaKolona);
                    if ( KojaKolona < 0 || KojaKolona > k ) {
                        printf("\n Kolona %d nije ispravno uneta! \n",KojaKolona);
                        exit(1);
                    }
                    prikaz_matrice_bez_kolone(M,r,k,KojaKolona);
                    break;
            case 5:         // Obrisi kolonu k matrice
                    printf("\n Koju kolonu zelis da obrises, k = ");
                    scanf("%d", &KojaKolona);
                    obrisi_kolonu_matrice(M,r,&k,KojaKolona);
                    break;
            case 6:         // Prikaz matrice bez reda r i kolone k

                    break;
            case 7:         // Obrisi red r i kolonu k matrice
                    printf("\n Koji red zelis da obrises, r = ");
                    scanf("%d", &KojiRed);
                    if ( KojiRed < 0 || KojiRed > r ) {
                        printf("\n Red %d nije ispravno unet! \n",KojiRed);
                        exit(1);
                    }
                    printf("\n Koju kolonu zelis da obrises, k = ");
                    scanf("%d", &KojaKolona);
                    if ( KojaKolona < 0 || KojaKolona > k ) {
                        printf("\n Kolona %d nije ispravno uneta! \n",KojaKolona);
                        exit(1);
                    }
                    obrisi_red_r_i_kolonu_k(M,&r,&k,KojiRed,KojaKolona);
                    break;
            case 8:         // Prikazi matricu bez glavne dijagonale
                    prikazi_matricu_bez_glavne_dijagonale(M,r,k);
                    break;
            case 9:         // Obrisi glavnu dijagonalu matrice
                    obrisi_glavnu_dijagonalu_matrice(M,r,&k);
                    break;
            case 10:        // Prikazi matricu bez sporedne dijagonale
                    prikazi_matricu_bez_sporedne_dijagonale(M,r,k);
                    break;
            case 11:        // Obrisi sporednu dijagonalu matrice
                    obrisi_sporednu_dijagonalu_matrice(M,r,&k);
                    break;
            case 12:        // Medjusobna zamena mesta dva reda
                    printf("\n Unesi redni broj prvog reda za medjusobnu zamenu mesta, r1 = ");
                    scanf("%d", &KojiRed);
                    if ( KojiRed < 0 || KojiRed > r ) {
                        printf("\n Red %d nije ispravno unet! \n",KojiRed);
                        exit(1);
                    }
                    printf("\n Unesi redni drugog reda za medjusobnu zamenu mesta, r2 = ");
                    scanf("%d", &KojaKolona); // ovde je iskoriscena promenljiva KojaKolona za unos reda
                    if ( KojaKolona < 0 || KojaKolona > r ) {
                        printf("\n Red %d nije ispravno unet! \n",KojaKolona);
                        exit(1);
                    }
                    medjusobna_zamena_mesta_dva_reda(M,r,k,KojiRed,KojaKolona);
                    break;
            case 13:        // Medjusobna zamena mesta dve kolone
                    printf("\n Unesi redni broj prve kolone za medjusobnu zamenu mesta, k1 = ");
                    scanf("%d", &KojiRed); // ovde je iskoriscena promenljiva KojRed za unos kolone
                    if ( KojiRed < 0 || KojiRed > k ) {
                        printf("\n Kolona %d nije ispravno uneta ! \n",KojiRed);
                        exit(1);
                    }
                    printf("\n Unesi redni broj druge kolone za medjusobnu zamenu mesta, k2 = ");
                    scanf("%d", &KojaKolona);
                    if ( KojaKolona < 0 || KojaKolona > k ) {
                        printf("\n Kolona %d nije ispravno uneta ! \n",KojaKolona);
                        exit(1);
                    }
                    medjusobna_zamena_mesta_dve_kolone(M,r,k,KojiRed,KojaKolona);
                    break;
            case 14:        // Formiraj matricu od rednih brojeva
                    printf("\n Unesi broj redova nove matrice, r = ");
                    scanf("%d", &r);
                    printf("\n Unesi broj kolona nove matrice, k = ");
                    scanf("%d", &k);
                    formiraj_matricu(M,r,k);
                    break;
            case 0:             // Kraj rada
                    kraj = 1;
                    break;
            default :
                    printf("\n\n \t Morate izabrati (0-14) ! \n\n");
                    break;
        } // switch(izbor)
    } // while(!kraj)
    return izbor;
} // glavni_meni()




int main(void)
{

    glavni_meni();


    return 0;
}