// punkt.cc, Ein erstes Beispiel fuer eine Klassendefinition
#include <math.h>
#include <iostream>
using namespace std;

class punkt {
  int x; int y;                   // geschuetzte Komponenten
public:                           // Schnittstelle zur "Aussenwelt",
                                  // in diesem Fall gegeben durch Klassenfunktionen:
  punkt();                        // Constructor-Funktion zur Definition
  punkt(int, int);                // Constructor-Funktion zur Initialisierung
  double dist();                  // Eine Member-Funktion
  friend double arg(punkt);       // Eine Friend-Funktion
  friend ostream& operator<<(ostream&, punkt);   // Ausgabeoperator
  friend bool operator>(punkt, punkt);           // Vergleichsoperator
  friend bool operator<(punkt, punkt);           // Vergleichsoperator
};

punkt::punkt() {};
punkt::punkt(int xx, int yy) { x = xx; y = yy; }

double punkt::dist() {      // Distanz zum Punkt (0,0)
   return sqrt(x*x+y*y);
}

double arg(punkt z) {       // Winkel der Richtung (0,0)-->(x,y) zur x-Achse
  return atan((double)z.y/(double)z.x);
}

ostream& operator<<(ostream& os, punkt z) {
   return os << '(' << z.x << ',' << z.y << ')';
}

bool operator>(punkt u, punkt v) {         // lexikographische Ordnung
  if (u.x == v.x)
    return (u.y > v.y);
  return (u.x > v.x);
}

bool operator<(punkt u, punkt v) {         // lexikographische Ordnung
  if (u.x == v.x)
    return (u.y < v.y);
  return (u.x < v.x);
}
//  Ende der Klassendefinition

#include "quicksort.h"            // enthaelt quicksort- und Swap-Template

int a[] = { 1, 2, 3, 4, 5 };

int s = sizeof(a)/sizeof(int);    // Anzahl der Elemente im Array a

int main() {
  punkt u;                        // Hier arbeitet punkt()

  cout << "Ausgabe: u = " << u << '\n';  // Hier arbeitet operator<< = Ausgabe

  u = punkt(1,2);                 // Hier arbeitet punkt(int,int)

  punkt v = punkt(3,4);           // Hier arbeiten beide punkt-Constructoren

  cout << "u = " << u << ", v = " << v << '\n';
  cout << "l(u) = " << u.dist() << ", l(v) = " << v.dist() << '\n';
  cout << "arg(u) = "<< arg(u) << ", arg(v) = " << arg(v) << '\n';

  if (u < v)
    cout << " u < v \n";          // Test fuer operator< : lexikographische O.
  else
    cout << " ! u < v \n";

  punkt w[s*s];                   // Array wird definiert.

  for (int i=0; i < s; i++)
    for (int j=0; j < s; j++) {
      w[i+j*s] = punkt(a[i],a[j]); // Array wird initialisiert
    }

  for (int i = 0; i < s*s; i++ ) {
    cout << w[i] << ' ';
    if ( i%s == s-1 )
      cout << '\n';                // Ausgabe des Arrays
  }

  cout << "quicksort arbeitet:\n";

  quicksort(w, s*s);

  for (int i = 0; i < s*s; i++ ) { // Ausgabe des geordneten Arrays
    cout << w[i] << ' ';
    if ( i%s == s-1 )
      cout << '\n';
  }
}
