﻿//----------------------
// <auto-generated>
// </auto-generated>
//----------------------







export class Address implements IAddress {
    foo!: string | undefined;

    constructor(data?: IAddress) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (this as any)[property] = (data as any)[property];
            }
        }
    }

    init(_data?: any) {
        if (_data) {
            this.foo = _data["Foo"];
        }
    }

    static fromJS(data: any): Address {
        data = typeof data === 'object' ? data : {};
        let result = new Address();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["Foo"] = this.foo;
        return data;
    }
}

export interface IAddress {
    foo: string | undefined;
}

export class Car implements ICar {
    foo!: string | undefined;

    constructor(data?: ICar) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (this as any)[property] = (data as any)[property];
            }
        }
    }

    init(_data?: any) {
        if (_data) {
            this.foo = _data["Foo"];
        }
    }

    static fromJS(data: any): Car {
        data = typeof data === 'object' ? data : {};
        let result = new Car();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["Foo"] = this.foo;
        return data;
    }
}

export interface ICar {
    foo: string | undefined;
}

export class Skill implements ISkill {
    foo!: string | undefined;

    constructor(data?: ISkill) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (this as any)[property] = (data as any)[property];
            }
        }
    }

    init(_data?: any) {
        if (_data) {
            this.foo = _data["Foo"];
        }
    }

    static fromJS(data: any): Skill {
        data = typeof data === 'object' ? data : {};
        let result = new Skill();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["Foo"] = this.foo;
        return data;
    }
}

export interface ISkill {
    foo: string | undefined;
}

export abstract class MyClass implements IMyClass {
    supervisor!: MyClass | undefined;
    address!: Address | undefined;
    cars!: Car[] | undefined;
    skills!: { [key: string]: Skill; } | undefined;
    foo!: Car[][] | undefined;
    bar!: { [key: string]: Skill[]; } | undefined;

    protected _discriminator: string;

    constructor(data?: IMyClass) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (this as any)[property] = (data as any)[property];
            }
            this.address = data.address && !(data.address as any).toJSON ? new Address(data.address) : this.address as Address;
            if (data.cars) {
                this.cars = [];
                for (let i = 0; i < data.cars.length; i++) {
                    let item = data.cars[i];
                    this.cars[i] = item && !(item as any).toJSON ? new Car(item) : item as Car;
                }
            }
            if (data.skills) {
                this.skills = {};
                for (let key in data.skills) {
                    if (data.skills.hasOwnProperty(key)) {
                        let item = data.skills[key];
                        this.skills[key] = item && !(item as any).toJSON ? new Skill(item) : item as Skill;
                    }
                }
            }
        }
        this._discriminator = "MyClass";
    }

    init(_data?: any) {
        if (_data) {
            this.supervisor = _data["Supervisor"] ? MyClass.fromJS(_data["Supervisor"]) : undefined as any;
            this.address = _data["Address"] ? Address.fromJS(_data["Address"]) : undefined as any;
            if (Array.isArray(_data["Cars"])) {
                this.cars = [] as any;
                for (let item of _data["Cars"])
                    this.cars!.push(Car.fromJS(item));
            }
            if (_data["Skills"]) {
                this.skills = {} as any;
                for (let key in _data["Skills"]) {
                    if (_data["Skills"].hasOwnProperty(key))
                        (this.skills as any)![key] = _data["Skills"][key] ? Skill.fromJS(_data["Skills"][key]) : new Skill();
                }
            }
            if (Array.isArray(_data["Foo"])) {
                this.foo = [] as any;
                for (let item of _data["Foo"])
                    this.foo!.push(item);
            }
            if (_data["Bar"]) {
                this.bar = {} as any;
                for (let key in _data["Bar"]) {
                    if (_data["Bar"].hasOwnProperty(key))
                        (this.bar as any)![key] = _data["Bar"][key] ? _data["Bar"][key].map((i: any) => Skill.fromJS(i)) : [];
                }
            }
        }
    }

    static fromJS(data: any): MyClass {
        data = typeof data === 'object' ? data : {};
        if (data["discriminator"] === "Student") {
            let result = new Student();
            result.init(data);
            return result;
        }
        throw new Error("The abstract class 'MyClass' cannot be instantiated.");
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["discriminator"] = this._discriminator;
        data["Supervisor"] = this.supervisor ? this.supervisor.toJSON() : undefined as any;
        data["Address"] = this.address ? this.address.toJSON() : undefined as any;
        if (Array.isArray(this.cars)) {
            data["Cars"] = [];
            for (let item of this.cars)
                data["Cars"].push(item ? item.toJSON() : undefined as any);
        }
        if (this.skills) {
            data["Skills"] = {};
            for (let key in this.skills) {
                if (this.skills.hasOwnProperty(key))
                    (data["Skills"] as any)[key] = this.skills[key] ? this.skills[key].toJSON() : undefined as any;
            }
        }
        if (Array.isArray(this.foo)) {
            data["Foo"] = [];
            for (let item of this.foo)
                data["Foo"].push(item);
        }
        if (this.bar) {
            data["Bar"] = {};
            for (let key in this.bar) {
                if (this.bar.hasOwnProperty(key))
                    (data["Bar"] as any)[key] = (this.bar as any)[key];
            }
        }
        return data;
    }
}

export interface IMyClass {
    supervisor: MyClass | undefined;
    address: IAddress | undefined;
    cars: ICar[] | undefined;
    skills: { [key: string]: ISkill; } | undefined;
    foo: Car[][] | undefined;
    bar: { [key: string]: Skill[]; } | undefined;
}

export class Student extends MyClass implements IStudent {
    course!: string | undefined;
    car!: Car | undefined;

    constructor(data?: IStudent) {
        super(data);
        if (data) {
            this.car = data.car && !(data.car as any).toJSON ? new Car(data.car) : this.car as Car;
        }
        this._discriminator = "Student";
    }

    override init(_data?: any) {
        super.init(_data);
        if (_data) {
            this.course = _data["Course"];
            this.car = _data["Car"] ? Car.fromJS(_data["Car"]) : undefined as any;
        }
    }

    static override fromJS(data: any): Student {
        data = typeof data === 'object' ? data : {};
        let result = new Student();
        result.init(data);
        return result;
    }

    override toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["Course"] = this.course;
        data["Car"] = this.car ? this.car.toJSON() : undefined as any;
        super.toJSON(data);
        return data;
    }
}

export interface IStudent extends IMyClass {
    course: string | undefined;
    car: ICar | undefined;
}