#include <stdio.h>		/* printf */
#include <stdlib.h>		/* malloc, abort */
#include <assert.h>

#include "matrix.h"

struct matrix *alloc_matrix(int num_rows, int num_columns)
{
  struct matrix *m = malloc(sizeof(struct matrix));
  if (m == NULL) {
    fprintf(stderr, "Allocation of memory failed\n");
    abort();
  }
  (*m).num_rows = num_rows;
  (*m).num_columns = num_columns;
  (*m).elements = malloc(sizeof(double) * num_rows * num_columns);
  if ((*m).elements == NULL) {
    fprintf(stderr, "Allocation of memory failed\n");
    abort();
  }
  return m;
}

/* Zugriffsfunktionen (Accessors) */

double matrix_element(struct matrix *matrix, int row, int column)
{
  return *((*matrix).elements + row * (*matrix).num_columns + column);
}

void set_matrix_element(struct matrix *matrix, int row, int column,
			double element)
{
  *((*matrix).elements + row * (*matrix).num_columns + column) = element;
}

/* Destruktor */

void free_matrix(struct matrix *matrix)
{
  free((*matrix).elements);
  free(matrix);
}

struct matrix *read_matrix()
{
  int num_rows;
  int num_columns;
  struct matrix *matrix;
  
  printf("Anzahl Zeilen:  ");
  scanf("%d", &num_rows);
  printf("Anzahl Spalten: ");
  scanf("%d", &num_columns);

  matrix = alloc_matrix(num_rows, num_columns);
  {
    int i, j;
    for (i = 0; i<num_rows; i++) {
      printf("Zeile %d: ", i);
      for (j = 0; j<num_columns; j++) {
	double element;
	scanf("%lf", &element);
	set_matrix_element(matrix, i, j, element);
      }
    }
  }
  return matrix;
}

void print_matrix(struct matrix *matrix)
{
  int i, j;
  for (i = 0; i<(*matrix).num_rows; i++) {
    for (j = 0; j<(*matrix).num_columns; j++)
      printf("%g ", matrix_element(matrix, i, j));
    printf("\n");
  }
}
