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



#define NUMALUNOS	10
#define NUMCADEIRAS	5
#define STRTAM		50


typedef struct{
	char nome[STRTAM];
	int nota;
}CADEIRAS;
typedef struct{
	char nome[STRTAM];
	int numero;
	int ncadeiras;
	CADEIRAS vcadeiras[NUMCADEIRAS];

}ALUNO;

/*retorna um valor entre o min e o max*/
int valor_aleatorio(int min, int max)
{
	return (((float)rand()/RAND_MAX)*(max-min)+min);
}

/* procura o aluno pelo numero */
/*
retorna -1 senão encontrou e a posicao do vector se encontrou
*/
int procura_aluno_numero(ALUNO v[],int n, int num)
{
	int i;
	for(i=0;i<n;i++)
		if(v[i].numero==num)
			return i;
	return -1;
}
/* procura a cadira pelo nome */
/*
retorna -1 senão encontrou e a posicao do vector se encontrou
*/

int procura_cadeira_nome(CADEIRAS v[],int n, char nome[])
{
	int i;
	for(i=0;i<n;i++)
		if(strcmp(v[i].nome, nome)==0)
			return i;
	return -1;
}

void listar_aluno(ALUNO *a)
{
	int j;
	printf("\nNumero: %d\n",(*a).numero);
	printf("Nome: %s\n",(*a).nome);
	printf("N cadeiras: %d\n",(*a).ncadeiras);
	printf("\tCadeira\tNota\n");
	for(j=0;j<(*a).ncadeiras;j++)
		printf("\t%s\t%d\n",(*a).vcadeiras[j].nome,(*a).vcadeiras[j].nota);

}

void inicializar_alunos(ALUNO v[],int *n)
{
	int i,j,x,k;
	/*declarar e inicializar matrizes com nomes*/
	char nomesalunos[10][STRTAM]={"Jose","Manuel","Maria","Rita","Pedro","Joaquim","Joana","Ana","Catarina","Joao"};
	char nomescadeiras[NUMCADEIRAS][STRTAM]={"APRO","MAT1","MAT2","TI","IT"};
	/*randomize();*/ /* no TC podem usar esta função*/
	srand( (unsigned)time( NULL ) );

	*n=valor_aleatorio(3, 8);/*inicializa entre 3 a 8 alunos*/
	for(i=0;i<*n;i++){
		k=valor_aleatorio(0, 9);
		strcpy(v[i].nome,nomesalunos[k]);
		do{
			k=valor_aleatorio(1000,2000);
			x=procura_aluno_numero(v,i,k);
		}while(x!=-1);
		v[i].numero=k;
		v[i].ncadeiras=valor_aleatorio(0, NUMCADEIRAS);
		for(j=0;j<v[i].ncadeiras;j++){
			do{
				k=valor_aleatorio(0, NUMCADEIRAS-1);
				x=procura_cadeira_nome(v[i].vcadeiras,j,nomescadeiras[k]);
			}while(x!=-1);
			strcpy(v[i].vcadeiras[j].nome,nomescadeiras[k]);
			v[i].vcadeiras[j].nota=valor_aleatorio(0, 20);
		}
	}
}
void inserir_cadeiras(CADEIRAS c[], int *n)
{
	char nome[STRTAM];
	int x,k;
	if(*n<NUMCADEIRAS){
		do{
			fflush(stdin);
			printf("Nome da cadeira:");
			gets(nome);
			x=procura_cadeira_nome(c,*n,nome);
		}while(x!=-1);

		strcpy(c[*n].nome,nome);
		do{
			printf("Nota: ");
			scanf("%d",&k);
		}while(k<0||k>20);
		c[*n].nota=k;
		(*n)++;
	}
}
void eliminar_cadeiras(CADEIRAS c[], int *n)
{
	char nome[STRTAM];
	int x,i;
	if(*n>0){
		do{
			fflush(stdin);
			printf("Nome da cadeira:");
			gets(nome);
			x=procura_cadeira_nome(c,*n,nome);
		}while(x!=-1);

		for(i=x;i<NUMCADEIRAS;i++){
			c[i]=c[i+1];
		}
		(*n)--;
	}
}
void inserir(ALUNO v[],int *n)
{
	int j,x,k;
	char nome[STRTAM];
	do{
		printf("Numero: ");
		scanf("%d",&k);
		x=procura_aluno_numero(v,*n,k);
	}while(x!=-1);
	v[*n].numero=k;
	fflush(stdin);
	printf("Nome: ");
	gets(v[*n].nome);
	do{
		printf("Numero de cadeiras: \n");
		scanf("%d",&k);
	}while(k<0 || k>NUMCADEIRAS);
	v[*n].ncadeiras=k;
	for(j=0;j<v[*n].ncadeiras;j++){
		do{
			fflush(stdin);
			printf("Nome da cadeira:");
			gets(nome);
			x=procura_cadeira_nome(v[*n].vcadeiras,j,nome);
		}while(x!=-1);
		strcpy(v[*n].vcadeiras[j].nome,nome);
		do{
			printf("Nota: ");
			scanf("%d",&k);
		}while(k<0||k>20);
		v[*n].vcadeiras[j].nota=k;
	}
	(*n)++;

}
void alterar(ALUNO v[],int n)
{
	int x,k,op,x1;
	char c;
	printf("Numero do aluno: ");
	scanf("%d",&k);
	x=procura_aluno_numero(v,n,k);
	if(x!=-1){
		listar_aluno(&v[x]);

		fflush(stdin);
		printf("Confirma que pretende alterar(s/n): ");
		c=getchar();
		if(tolower(c)=='s'){
			fflush(stdin);
			printf("Pretende alterar o numero(s/n): ");
			c=getchar();
			if(tolower(c)=='s'){
				do{
					printf("Numero: ");
					scanf("%d",&k);
					x1=procura_aluno_numero(v,n,k);
				}while(x1!=-1);
				v[x].numero=k;
			}
			fflush(stdin);
			printf("Pretende alterar o nome(s/n): ");
			c=getchar();
			if(tolower(c)=='s'){
				fflush(stdin);
				printf("Nome: ");
				gets(v[x].nome);
			}
			fflush(stdin);
			printf("Pretende alterar a informação das cadeiras(s/n): ");
			c=getchar();
			if(tolower(c)=='s'){
				do {
					printf("\n\n - - - - CADEIRAS - - - -\n");
					printf(" 1 - Inserir cadeiras \n");
					printf(" 2 - Eliminar cadeiras\n");
					printf(" 0 - Sair \n");
					printf(" Opcao --> ");
					scanf("%d",&op);						
					switch(op) {
						case 1: inserir_cadeiras(v[x].vcadeiras,&v[x].ncadeiras);
						break;
						case 2: eliminar_cadeiras(v[x].vcadeiras,&v[x].ncadeiras);
						break;
					}					
				} while(op);
			}			
		}
	}
}

void eliminar(ALUNO v[],int *n)
{
	int x,k,i;
	char c;
	printf("Numero do aluno: ");
	scanf("%d",&k);
	x=procura_aluno_numero(v,*n,k);
	if(x!=-1){
		listar_aluno(&v[x]);
		fflush(stdin);
		printf("Confirma que pretende eliminar(s/n): ");
		c=getchar();
		if(tolower(c)=='s'){
			for(i=x;i<*n;i++)
				v[i]=v[i+1];
			(*n)--;
		}
	}

}
void listar(ALUNO v[],int n)
{
	int i;
	printf("\n\n******Listagem******\n");
	for(i=0;i<n;i++)
		listar_aluno(&v[i]);
	
}

void listar_por_cadeira(ALUNO v [], int n)
{
	int i,j;
	char nome[STRTAM];
	fflush(stdin);
	printf("introduza a cadeira");
	gets(nome);
	for(i=0;i<n;i++)
	{
		for(j=0;j<v[i].ncadeiras;j++)
		{
			if(strcmp(v[i].vcadeiras[j].nome,nome)==0)
			{
				printf("NOME: %s\n",v[i].nome);
				printf("NUMERO: %d\n",v[i].numero);
				printf("NOTA: %d\n",v[i].vcadeiras[j].nota);
			}
		}
	}
}

int media(ALUNO *a)
{
	int media=0,soma=0,i;
	for(i=0;i<(*a).ncadeiras;i++)
	{
		soma=soma+(*a).vcadeiras[i].nota;
	}
	
	if(a->ncadeiras!=0)
		media=soma/(*a).ncadeiras;
	
	return media; 
}


void ordenar_media(ALUNO valunos[], int nalunos)
{
	ALUNO tmp;
	int i,j;

	for (i=0; i<(nalunos-1); i++){
		for(j=(i+1); j<nalunos; j++){
			if(media(&valunos[i]) > media(&valunos[j]))
			{
				tmp = valunos[i];
				valunos[i]=valunos[j];
				valunos[j]=tmp;
			}
		}
	}
}

void main() {
	ALUNO valunos[NUMALUNOS];/*vector de alunos*/
	int nalunos=0; /*numero de alunos que efectivamente existem*/
	int opcao;
	inicializar_alunos(valunos,&nalunos);
	do {
		printf("\n\n - - - - ALUNOS - - - -\n");
		printf(" 1 - Inserir \n");
		printf(" 2 - Alterar \n");
		printf(" 3 - Eliminar \n");
		printf(" 4 - Listar \n");
		printf(" 5 - Ordenar por media \n");
		printf(" 6 - Listar por cadira\n");
		printf(" 0 - Sair \n");
		printf(" Opcao --> ");
		scanf("%d",&opcao);
		
		switch(opcao) {
			case 1: inserir(valunos,&nalunos);
			break;
			case 2: alterar(valunos,nalunos);
			break;
			case 3: eliminar(valunos,&nalunos);
			break;
			case 4: listar(valunos,nalunos);
			break;
			case 5: ordenar_media(valunos,nalunos);
			break;
			case 6: listar_por_cadeira(valunos,nalunos);
			break;
		}
		
	} while(opcao);
}
