void Start()
    {
        layoutItemUI = transform.Find("ItemList").GetComponent <LayoutItemUI>();

        // find buttons
        useButton  = transform.Find("Info/Buttons/ButtonUse").gameObject;
        dropButton = transform.Find("Info/Buttons/ButtonDrop").gameObject;
        buttons    = new GameObject[] { useButton, dropButton };
        fillButton(Color.gray);

        // init values
        state       = BagUIState.VIEW_ITEM;
        hasNextPage = false;
        pageIndex   = 0;
        cursorIndex = 0;
        itemUIs     = layoutItemUI.place(maxPageSize);
        bagSize     = Bag.bag_ins.GetBagSize();
        buttonIndex = 0;

        // find ui elements
        itemImage       = GameObject.Find("Info/Image").GetComponent <Image>();
        descriptionText = GameObject.Find("Info/Description").GetComponent <Text>();

        // redraw
        redrawItemList();
        redrawInfoPanel();
    }
    private void itemPanelHandle()
    {
        // update cursor index
        // and check bound (turn page)

        currentItem.unselect();

        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            cursorIndex--;
            if (cursorIndex < 0 && pageIndex > 0)
            {
                pageIndex--;
                cursorIndex = maxPageSize - 1;
                redrawItemList();
            }
            cursorIndex = Mathf.Max(0, cursorIndex);
        }
        else if (Input.GetKeyDown(KeyCode.DownArrow))
        {
            cursorIndex++;
            if (hasNextPage && cursorIndex >= pageSize)
            {
                pageIndex++;
                cursorIndex = 0;
                redrawItemList();
            }
            else if (cursorIndex >= pageSize)
            {
                cursorIndex = pageSize - 1;
            }
        }
        // TODO: config for key
        // enter view info state?
        else if (Input.GetKeyDown(KeyCode.Z))
        {
            // set use button as default
            buttonIndex = 0;
            fillButton(Color.white);
            state = BagUIState.VIEW_INFO;
        }
        // exit page
        else if (Input.GetKeyDown(KeyCode.Escape))
        {
            player.gameObject.SetActive(true);
            Destroy(gameObject);
        }

        currentItem.select();
        redrawInfoPanel();
    }
    private void infoPanelHandle()
    {
        // use left and right arrow key to select button
        // z to invoke action
        // esc to escape

        // move
        buttons[buttonIndex].GetComponent <Image>().color = Color.white;
        if (Input.GetKeyDown(KeyCode.LeftArrow))
        {
            buttonIndex--;
        }
        else if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            buttonIndex++;
        }
        buttonIndex = (buttonIndex + BUTTON_COUNT) % BUTTON_COUNT;
        buttons[buttonIndex].GetComponent <Image>().color = Color.red;

        // select
        if (Input.GetKeyDown(KeyCode.Z))
        {
            switch (buttonIndex)
            {
            // use
            case 0:
                if (Bag.bag_ins.CheckItemEvent(itemIndex, ItemEvent.Use))
                {
                    Bag.bag_ins.ExecuteItemEvent(itemIndex, ItemEvent.Use);
                }
                break;

            // drop
            case 1:
                if (Bag.bag_ins.CheckItemEvent(itemIndex, ItemEvent.Use))
                {
                    Bag.bag_ins.ExecuteItemEvent(itemIndex, ItemEvent.Drop);
                }
                break;
            }
        }
        // exit
        else if (Input.GetKeyDown(KeyCode.Escape))
        {
            fillButton(Color.gray);
            state = BagUIState.VIEW_ITEM;
        }
    }