function User(username, email) {
    this.username = username;
    this.email = email;

    this.login = function () {
        console.log(`The user ${this.username} logged in!`);
    }

    this.logout = function () {
        console.log(`The user ${this.username} logged out!`);
    }
}

User.prototype.login = function () { // Collection der prototype Funktionen in __proto__ Sammlung "User.prototype"
    console.log(`${this} wurde angemeldet`);
    return this;
}

User.prototype.logout = function () { // Collection der prototype Funktionen in __proto__ Sammlung "User.prototype"
    console.log(`${this} wurde abgemeldet`);
    return this;
}

// const userOne = new User("davida", "davida@gmail.com")
// const userTwo = new User("joanne", "joanne@gmail.com")
// userOne.login();

// *** das Gleiche da unten ***

// class User {

//     constructor(username, email) {
//         console.log("new User wurde erstellt");
//         //einstellen der Properties für das Object
//         this.username = username;
//         this.email = email;
//         this.score = 0;
//     }

//     login() {
//         console.log(`The user ${this.username} logged in!`);
//         return this;
//         // Eine Methode-Verkettung kann man nur dann benutzen, wenn eine Methode eine Instance des Selbst-Objektes zurückgibt
//         // (Anweisung "this" referiert auf sein eigenes Objekt)
//     }

//     logout() {
//         console.log(`The user ${this.username} logged out!`);
//         return this;
//     }

//     printUserData() {
//         console.log(`username: ${this.username}, email: ${this.email}!`)
//     }

//     incScore() {
//         this.score++;
//         console.log(`${this.username} has a score of ${this.score}`)
//         return this;
//     }
// }

// class Admin extends User {
//     constructor(username, email, title) {
//         super(username, email); // damit wird erst der Konstruktor der Eltern Klasse (User- Generalization Class) ausgeführt,
//         // dannach wird der Konstruktor der User Klasse ausgeführt. Am Ende des Konstruktors wird die Eigenschaft title ausgeführt und zugewissen.
//         this.title = title;
//     }

//     deleteUser(user) { // mit einem Admin-Objekt kann man mithilfe der deleteUser() Methode,
//         // einen User aus dem Feld entfernen (filter() Methode hilft dabei, um User, den die Beziehung entspricht, zu entfernen)
//         users = users.filter((u) => {
//             return u.username !== user.username;
//         });
//     }
// }

// *** Das Gleiche da oben ***
function Admin(username, email, title) { // Definition einer Admin Klasse, die von der User Klasse(spezializierte Klasse) abgeleitet ist
    User.call(this, username, email); // mit der Object.call() Methode wird der Konstruktor in der User Klasse ausgeführt
    // (this parameter referiert auf die Instance des User Objektes, der Parameter username und email referiert auf die Eigenschaften des User Objektes
    this.title = title;
}

Admin.prototype = Object.create(User.prototype); // damit die Admin Klasse die prototype Methoden aus der User Klasse bekommt



// *** DIE AUSGABEN DER OBJEKTEN UND OBJEKT-ERSTELLUNGEN ***

// const userOne = new User("David", "davida@gmail.com");
// const userTwo = new User("Nika", "nikaa@gmail.com");
// const userThree = new Admin("Joanne", "joannea@gmail.com", "lead entwickler");

// console.log(userOne, userTwo, userThree);
// let users = [userOne, userTwo, userThree];

// console.log(users);
// userThree.deleteUser(userTwo);
// console.log(users); 