/*---------------------------------------------------------------------------*/
/* car_play.h                                                                */
/* copyright (c) innovaphone 2018                                            */
/*                                                                           */
/*---------------------------------------------------------------------------*/

class CPImageSet {
public:
    CPImageSet(byte *lightContentImage, unsigned lightContentImageLength, byte *darkContentImage = NULL, unsigned darkContentImageLength = 0);
    virtual ~CPImageSet();

    byte *lightContentImage;
    unsigned lightContentImageLength;
    byte *darkContentImage;
    unsigned darkContentImageLength;
};

class CPCompletion {
public:
    virtual ~CPCompletion() {};

    virtual void complete() = 0;
};

class CPTemplate {
public:
    void *userInfo;

    CPTemplate();
    virtual ~CPTemplate();
};

/*---------------------------------------------------------------------------*/

class CPListItem {
public:
    CPListItem(const char *text, const char *detailText, CPImageSet *image = NULL);
    virtual ~CPListItem();

    void *userInfo;
    char *text;
    void setText(const char *text);
    char *detailText;
    void setDetailText(const char *detailText);
    CPImageSet *image;
    void setImage(CPImageSet *image);
};

class CPListSection {
public:
    CPListSection(CPListItem **items, unsigned itemCount);
    CPListSection(CPListItem **items, unsigned itemCount, const char *header, const char *sectionIndexTitle);
    virtual ~CPListSection();

    CPListItem **items;
    unsigned itemCount;
    unsigned indexOfItem(CPListItem *item);
    CPListItem *itemAtIndex(unsigned index);
    char *header;
    char *sectionIndexTitle;
};

class CPListTemplateDelegate {
public:
    virtual void listTemplateDidSelectListItem(class CPListTemplate *listTemplate, CPListItem *item, CPCompletion *completion) = 0;
};

class CPListTemplate : public CPTemplate {
public:
    CPListTemplate(const char *title, CPListSection **sections, unsigned sectionCount);
    virtual ~CPListTemplate();

    CPListTemplateDelegate *delegate;
    CPListSection **sections;
    unsigned sectionCount;
    void updateSections(CPListSection **sections, unsigned sectionCount);
    char *title;
};

/*---------------------------------------------------------------------------*/

class CPGridButtonHandler {
public:
    virtual void gridButtonHandleSelection(class CPGridButton *gridButton) = 0;
};

class CPGridButton {
    bool enabled;
public:
    CPGridButton(const char **titleVariants, unsigned titleVariantCount, CPImageSet *image, CPGridButtonHandler *handler);
    virtual ~CPGridButton();

    CPGridButtonHandler *handler;
    char **titleVariants;
    unsigned titleVariantCount;
    CPImageSet *image;
    void setEnabled(bool enabled);
    bool isEnabled();
};

class CPGridTemplate : public CPTemplate {
public:
    CPGridTemplate(const char *title, CPGridButton **gridButtons, unsigned gridButtonCount);
    virtual ~CPGridTemplate();

    CPGridButton **gridButtons;
    unsigned gridButtonCount;
    char *title;
    void updateTitle(const char *title);
    void updateGridButtons(CPGridButton **gridButtons, unsigned buttonCount);
};

/*---------------------------------------------------------------------------*/

enum CPAlertActionStyle {
    CPAlertActionStyleDefault,
    CPAlertActionStyleCancel,
    CPAlertActionStyleDestructive,
};

class CPAlertActionHandler {
public:
    virtual void alertActionHandleSelection(class CPAlertAction *action) = 0;
};

class CPAlertAction {
public:
    CPAlertAction(const char *title, enum CPAlertActionStyle style, CPAlertActionHandler *handler);
    virtual ~CPAlertAction();

    CPAlertActionHandler *handler;
    char *title;
    enum CPAlertActionStyle style;
};

class CPAlertTemplate : public CPTemplate {
public:
    CPAlertTemplate(const char **titleVariants, unsigned titleVariantCount, CPAlertAction **actions, unsigned actionCount);
    virtual ~CPAlertTemplate();

    char **titleVariants;
    unsigned titleVariantCount;
    CPAlertAction **actions;
    unsigned actionCount;
};

/*---------------------------------------------------------------------------*/

class CPInterfaceControllerDelegate {
public:
    virtual void templateWillAppear(CPTemplate *aTemplate, bool animated) {};
    virtual void templateDidAppear(CPTemplate *aTemplate, bool animated) {};
    virtual void templateWillDisappear(CPTemplate *aTemplate, bool animated) {};
    virtual void templateDidDisappear(CPTemplate *aTemplate, bool animated) {};
};

class CPInterfaceController {
public:
    CPInterfaceControllerDelegate *delegate;
    CPTemplate *presentedTemplate;
    CPTemplate *rootTemplate;
    CPTemplate *topTemplate;
    CPTemplate **templates;
    unsigned templateCount;

    virtual ~CPInterfaceController() {};
    virtual void setRootTemplate(CPTemplate *rootTemplate, bool animated) = 0;
    virtual void pushTemplate(CPTemplate *templateToPush, bool animated) = 0;
    virtual void popTemplate(bool animated) = 0;
    virtual void popToRootTemplate(bool animated) = 0;
    virtual void popToTemplate(CPTemplate *targetTemplate , bool animated) = 0;
    virtual void presentTemplate(CPTemplate *templateToPresent , bool animated) = 0;
    virtual void dismissTemplate(bool animated) = 0;
};

class CPApplicationDelegate {
public:
    virtual void didConnectCarInterfaceController(CPInterfaceController *interfaceController) = 0;
    virtual void didDisconnectCarInterfaceController(CPInterfaceController *interfaceController) = 0;
};

class CarPlay {
public:
static void Use(CPApplicationDelegate *user);
};
