
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#ifndef SkOSMenu_DEFINED
#define SkOSMenu_DEFINED

#include "SkEvent.h"
#include "SkTDArray.h"

class SkOSMenu {
public:
    explicit SkOSMenu(const char title[] = "");
    ~SkOSMenu();

    /**
     * Each of these (except action) has an associated value, which is stored in
     * the event payload for the item.
     * Each type has a specific type for its value...
     *     Action : none
     *     List : int (selected index)
     *     Segmented : int (selected index)
     *     Slider : float
     *     Switch : bool
     *     TextField : string
     *     TriState : TriState
     *     Custom : custom object/value
     */
    enum Type {
        kAction_Type,
        kList_Type,
        kSlider_Type,
        kSwitch_Type,
        kTriState_Type,
        kTextField_Type,
        kCustom_Type
    };

    enum TriState {
        kMixedState = -1,
        kOffState = 0,
        kOnState = 1
    };

    class Item {
    public:
        /**
         * Auto increments a global to generate an unique ID for each new item
         * Note: Thread safe
         */
        Item(const char label[], SkOSMenu::Type type, const char slotName[],
             SkEvent* evt);
        ~Item() { delete fEvent; }

        SkEvent*    getEvent() const { return fEvent; }
        int         getID() const { return fID; }
        const char* getLabel() const { return fLabel.c_str(); }
        const char* getSlotName() const { return fSlotName.c_str(); }
        Type        getType() const { return fType; }
        void        setKeyEquivalent(SkUnichar key) { fKey = key; }
        SkUnichar   getKeyEquivalent() const { return fKey; }

        /**
         * Helper functions for predefined types
         */
        void setBool(bool value) const;             //For Switch
        void setScalar(SkScalar value) const;       //For Slider
        void setInt(int value) const;               //For List
        void setTriState(TriState value) const;     //For Tristate
        void setString(const char value[]) const;   //For TextField

        /**
         * Post event associated with the menu item to target, any changes to
         * the associated event must be made prior to calling this method
         */
        void postEvent() const { (new SkEvent(*(fEvent)))->post(); }

    private:
        int             fID;
        SkEvent*        fEvent;
        SkString        fLabel;
        SkString        fSlotName;
        Type            fType;
        SkUnichar       fKey;
    };

    void        reset();
    const char* getTitle() const { return fTitle.c_str(); }
    void        setTitle (const char title[]) { fTitle.set(title); }
    int         getCount() const { return fItems.count(); }
    const Item* getItemByID(int itemID) const;
    void        getItems(const Item* items[]) const;

    /**
     * Assign key to the menu item with itemID, will do nothing if there's no
     * item with the id given
     */
    void        assignKeyEquivalentToItem(int itemID, SkUnichar key);
    /**
     * Call this in a SkView's onHandleChar to trigger any menu items with the
     * given key equivalent. If such an item is found, the method will return
     * true and its corresponding event will be triggered (default behavior
     * defined for switches(toggling), tristates(cycle), and lists(cycle),
     * for anything else, the event attached is posted without state changes)
     * If no menu item can be matched with the key, false will be returned
     */
    bool        handleKeyEquivalent(SkUnichar key);

    /**
     * The following functions append new items to the menu and returns their
     * associated unique id, which can be used to by the client to refer to
     * the menu item created and change its state. slotName specifies the string
     * identifier of any state/value to be returned in the item's SkEvent object
     * NOTE: evt must be dynamically allocated
     */
    int appendItem(const char label[], Type type, const char slotName[],
                   SkEvent* evt);

    /**
     * Create predefined items with the given parameters. To be used with the
     * other helper functions below to retrive/update state information.
     * Note: the helper functions below assume that slotName is UNIQUE for all
     * menu items of the same type since it's used to identify the event
     */
    int appendAction(const char label[], SkEventSinkID target);
    int appendList(const char label[], const char slotName[],
                   SkEventSinkID target, int defaultIndex, const char[] ...);
    int appendSlider(const char label[], const char slotName[],
                     SkEventSinkID target, SkScalar min, SkScalar max,
                     SkScalar defaultValue);
    int appendSwitch(const char label[], const char slotName[],
                     SkEventSinkID target, bool defaultState = false);
    int appendTriState(const char label[], const char slotName[],
                       SkEventSinkID target, TriState defaultState = kOffState);
    int appendTextField(const char label[], const char slotName[],
                        SkEventSinkID target, const char placeholder[] = "");


    /**
     * Helper functions to retrieve information other than the stored value for
     * some predefined types
     */
    static bool FindListItemCount(const SkEvent& evt, int* count);
    /**
     * Ensure that the items array can store n SkStrings where n is the count
     * extracted using FindListItemCount
     */
    static bool FindListItems(const SkEvent& evt, SkString items[]);
    static bool FindSliderMin(const SkEvent& evt, SkScalar* min);
    static bool FindSliderMax(const SkEvent& evt, SkScalar* max);

    /**
     * Returns true if an action with the given label is found, false otherwise
     */
    static bool FindAction(const SkEvent& evt, const char label[]);
    /**
     * The following helper functions will return true if evt is generated from
     * a predefined item type and retrieve the corresponding state information.
     * They will return false and leave value unchanged if there's a type
     * mismatch or slotName is incorrect
     */
    static bool FindListIndex(const SkEvent& evt, const char slotName[], int* value);
    static bool FindSliderValue(const SkEvent& evt, const char slotName[], SkScalar* value);
    static bool FindSwitchState(const SkEvent& evt, const char slotName[], bool* value);
    static bool FindTriState(const SkEvent& evt, const char slotName[], TriState* value);
    static bool FindText(const SkEvent& evt, const char slotName[], SkString* value);

private:
    SkString fTitle;
    SkTDArray<Item*> fItems;

    // illegal
    SkOSMenu(const SkOSMenu&);
    SkOSMenu& operator=(const SkOSMenu&);
};

#endif
