
"""
FuzzyDate is used to specify an inexact date.
"Operator" can be used to signify "before", "after", "approximately", etc. 
"Comment" is for extra detail if needed.
Any of the "Day", "Month", or "Year" fields can be set or left empty as required.
"""
type FuzzyDate {
    Operator: String
    Day: Int
    Month: Int
    Year: Int
    Comment: String
}


type User {
    ID: Int!
    Name: String!
    Email: String
    Password: String

    MaintainerOf: UserRecords

    # Enhanced Data
    uuid: String
    date_created: String
    date_pdated: String
    deleted: Boolean
    date_deleted: String
}

type UserRecords {
    ReleaseIDs: [Int]
    GroupIDs: [Int]
    ScenerIDs: [Int]
    HandleIDs: [Int]
    EventIDs: [Int]
    BBSIDs: [Int]
    SIDIDs: [Int]
}



"""
A Release is a unique item or collection of files
"""
type Release {
    ID: Int!
    Name: String!
    """Alternative name"""
    AKA: String
    Type: String        # should go in tag
    GfxType: String     # should go in tag
    """Average rating based on votes"""
    Rating: Float
    """Identifies when item was first made public"""
    ReleaseDate: [FuzzyDate]

    """Event that item was first introduced"""
    ReleasedAt: Int
    ReleasedAtEvent: Event
    Achievement: ReleaseAchievement
    ReleasedBy: ReleaseGroupsHandles

    """Credits identify who worked on what parts of the item"""
    Credits: [ReleaseCredit]

    Website: String
    ScreenShot: [String]
    DownloadLinks: [ReleaseDownload]
    OtherLinks: [ReleaseLink]

    """Comments on various aspects of the item"""
    Comments: [ReleaseComment]

    """SID music used in this release"""
    SIDIDs: [Int]
    SIDs: [SID]

    # Enhanced Data
    """Unique GUID"""
    uuid: String
    """
    Tags are used for search and grouping by category.
    Types of tags are Automated, Required, and Optional.
    """
    tags: [String]
    """
    Parent ID is used to identify and group different versions of the same release.
    It should be set to the origial Release ID.
    https://github.com/idolpx/csdb-ng/issues/13
    """
    parent_id: Int
    date_created: String
    date_pdated: String
    deleted: Boolean
    date_deleted: String
}

type ReleaseAchievement {
    Compo: String
    Place: Int
}

type ReleaseGroupsHandles {
    GroupIDs: [Int]
    Groups: [Group]
    HandleIDs: [Int]
    Handles: [Handle]
}

type ReleaseCredit {
    CreditType: String!
    HandleIDs: [Int]
    Handles: [Handle]
}

type ReleaseLink {
    Title: String
    Link: String!
    CounterLink: String!
    Clicks: Int
}

type ReleaseDownload {
    CounterLink: String!
    Downloads: Int
    Filename: String
    Link: String!
    Status: String
    hash: String
}

type ReleaseComment {
    Summary: [ReleaseCommentData]
    Trivia: [ReleaseCommentData]
    Goof: [ReleaseCommentData]
    HiddenPart: [ReleaseCommentData]
    ProductionNote: [ReleaseCommentData]
    UserComment: [ReleaseCommentData]
}

type ReleaseCommentData {
    Date: Int!
    HandleID: Int!
    Handle: Handle
    Text: String!
}




type Group {
    ID: Int!
    Name: String!
    AKA: String
    Short: String
    Rating: Float
    Trivia: String
    BaseCountry: String

    FoundDate: [FuzzyDate]
    DissolveDate: [FuzzyDate]

    Website: String
    Grouptypes: [String]
    Slogan: [String]

    FounderHandleIDs: [Int]
    FounderHandles: [Handle]
    OrganizedEventIDs: [Int]
    OrganizedEvents: [Event]
    Members: [GroupMember]

    ReleaseIDs: [Int]
    Releases: [Release]
    BBSIDs: [Int]
    BBSs: [BBS]

    UserComment: [GroupCommentData]

    # Enhanced Data
    CoOpGroupIDs: [Int]
    CoOpGroups: [Group]

    uuid: String
    tags: [String]
    date_created: String
    date_pdated: String
    deleted: Boolean
    date_deleted: String
}

type GroupCommentData {
    Date: Int!
    HandleID: Int!
    Handle: Handle
    Text: String!
}

type GroupMember {
    HandleID: Int
    Handle: Handle
    """
    Groups can be member of another group
    https://github.com/idolpx/csdb-ng/issues/7
    """
    GroupID: Int
    Group: Group

    Profession: [String]

    JoinDate: [FuzzyDate]
    LeaveDate: [FuzzyDate]

    Status: String
}




type Scener {
    ID: Int!
    RegisterdDate: String
    Country: String

    BirthDate: [FuzzyDate]
    DeathDate: [FuzzyDate]

    HandleIDs: [Int]
    Handles: [Handle]

    # Enhanced Data
    uuid: String
    tags: [String]
    date_created: String
    date_pdated: String
    deleted: Boolean
    date_deleted: String
}




type Handle {
    ID: Int!
    Handle: String!
    CurrentlyUsedHandle: Boolean
    HandleStory: String
    FreelanceFunctions: [String]
    MemberOf: [HandleGroup]
    Credits: [HandleCredit]

    FoundedGroupIDs: [Int]
    FoundedGroups: [Group]
    MemberGroupIDs: [Int]
    MemberGroups: [Group]

    OrganizedEventIDs: [Int]
    OrganizedEvents: [Event]
    AttendedEventIDs: [Int]
    AttendedEvents: [Event]

    BBSSysopIDs: [Int]
    BBSSysop: [BBS]
    BBSUserIDs: [Int]
    BBSUser: [BBS]

    ReleaseIDs: [Int]
    Releases: [Release]
    ScenerIDs: [Int]
    Sceners: [Scener]

    # Enhanced Data
    uuid: String
    tags: [String]
    date_created: String
    date_pdated: String
    deleted: Boolean
    date_deleted: String
}

type HandleGroup {
    GroupID: Int!
    MemberStats: GroupMember
    Group: Group
}

type HandleCredit {
    CreditType: String!
    ReleaseIDs: [Int]
    Releases: [Release]
}




type Event {
    ID: Int!
    Name: String!
    EventType: [String]
    AKA: String
    Tagline: String

    StartDate: [FuzzyDate]
    EndDate: [FuzzyDate]

    Address: String
    City: String
    State: String
    Zip: String
    Country: String
    Website: String

    Organizers: EventOrganizers
    Compo: [EventCompo]
    PartyReport: [EventReport]
    UserComment: [EventComment]

    # Enhanced Data
    uuid: String
    tags: [String]
    date_created: String
    date_pdated: String
    deleted: Boolean
    date_deleted: String
}

type EventCompo {
    Type: String
    ReleaseIDs: [Int]
    Releases: [Release]
}

type EventReport {
    HandleID: Int!
    WrittenBy: String
    Date: Int
    Headline: String
    Text: String
    Handle: Handle
}

type EventComment {
    HandleID: Int!
    Date: Int!
    Text: String!
    Handle: Handle
}

type EventOrganizers {
    GroupIDs: [Int]
    Groups: [Group]
    HandleIDs: [Int]
    Handles: [Handle]
}




type BBS {
    ID: Int!
    Name: String!
    Short: String
    Trivia: String
    OnlinePeriod: [BBSOnlinePeriod]
    Phone: String
    Host: String
    Port: Int
    City: String
    State: String
    Country: String

    Sysop: [BBSSysop]
    Status: String

    GroupIDs: [Int]
    Groups: [Group]
    HandleIDs: [Int]
    Handles: [Handle]

    # Enhanced Data
    uuid: String
    tags: [String]
    date_created: String
    date_pdated: String
    deleted: Boolean
    date_deleted: String
}

type BBSOnlinePeriod {
    StartDate: [FuzzyDate]
    EndDate: [FuzzyDate]
}

type BBSSysop {
    Type: String
    HandleID: Int
    Handle: Handle
}




type SID {
    ID: Int!
    HVSCPath: String
    Name: String
    Author: String
    Released: String
    LoadAddr: Int
    InitAddr: Int
    PlayAddr: Int
    NOSongs: Int
    DefaultSong: Int
    SIDModel: String
    ClockSpeed: String
    DataSize: Int

    ReleaseIDs: [Int]
    Releases: [Release]

    # Enhanced Data
    uuid: String
    tags: [String]
    date_created: String
    date_pdated: String
    deleted: Boolean
    date_deleted: String
}


type SearchResult {
    id: Int
    name: String
    tags: String
}



type Query {
    release(id: Int!) : Release
    releases(ids: [Int]!) : [Release]

    group(id: Int!) : Group
    groups(ids: [Int]!) : [Group]

    scener(id: Int!) : Scener
    sceners(ids: [Int]!) : [Scener]

    handle(id: Int!) : Handle
    handles(ids: [Int]!) : [Handle]

    event(id: Int!) : Event
    events(ids: [Int]!) : [Event]

    bbs(id: Int!) : BBS
    bbss(ids: [Int]!) : [BBS]

    sid(id: Int!) : SID
    sids(ids: [Int]!) : [SID]

    search(query: String) : [Release]
}

type Mutation {
    createRelease(id: Int!) : Release
    createGroup(id: Int!) : Group
    createScener(id: Int!) : Scener
    createHandle(id: Int!) : Handle
    createEvent(id: Int!) : Event
    createBBS(id: Int!) : BBS
    createSID(id: Int!) : SID

    updateRelease(id: Int!) : Release
    updateGroup(id: Int!) : Group
    updateScener(id: Int!) : Scener
    updateHandle(id: Int!) : Handle
    updateEvent(id: Int!) : Event
    updateBBS(id: Int!) : BBS
    updateSID(id: Int!) : SID

    deleteRelease(id: Int!) : Release
    deleteGroup(id: Int!) : Group
    deleteScener(id: Int!) : Scener
    deleteHandle(id: Int!) : Handle
    deleteEvent(id: Int!) : Event
    deleteBBS(id: Int!) : BBS
    deleteSID(id: Int!) : SID
}
