#include "../../baygui.h"

namespace baygui {
    namespace awt {
        /** 未チェック（パレット） */
        static unsigned int unchecked_palette[] = {
            0xff040204,
            0xff8c8e8c,
            0xffe4e2e4,
            0xff4c4e4c,
            0xffb4b2b4,
            0xfffcfefc,
            0xffc0c0c0, /* 背景色 */
            0xffeceeec,
            0xff5c5e5c,
            0xffc4c2c4,
        };

        /** 未チェック（データ）*/
        static unsigned char unchecked_data[] = {
            0x6,0x6,0x6,0x6,0x3,0x0,0x0,0x3,0x6,0x6,0x6,0x6,
            0x6,0x6,0x0,0x8,0x2,0x2,0x2,0x9,0x3,0x0,0x6,0x6,
            0x6,0x0,0x9,0x2,0x7,0x5,0x5,0x5,0x2,0x1,0x0,0x6,
            0x6,0x8,0x2,0x7,0x5,0x5,0x7,0x7,0x2,0x9,0x3,0x6,
            0x3,0x2,0x7,0x5,0x5,0x7,0x7,0x7,0x2,0x9,0x1,0x3,
            0x0,0x2,0x5,0x5,0x7,0x7,0x2,0x2,0x9,0x9,0x1,0x0,
            0x0,0x2,0x5,0x7,0x7,0x7,0x2,0x9,0x9,0x4,0x1,0x0,
            0x3,0x9,0x5,0x7,0x2,0x2,0x9,0x9,0x4,0x4,0x1,0x3,
            0x6,0x8,0x2,0x2,0x2,0x9,0x9,0x4,0x4,0x1,0x3,0x6,
            0x6,0x0,0x1,0x9,0x9,0x9,0x4,0x4,0x1,0x1,0x0,0x6,
            0x6,0x6,0x0,0x8,0x1,0x1,0x1,0x1,0x3,0x0,0x6,0x6,
            0x6,0x6,0x6,0x6,0x3,0x0,0x0,0x3,0x6,0x6,0x6,0x6,
        };

        /** チェック（パレット） */
        static unsigned int checked_palette[] = {
            0xff040204,
            0xff8c8e8c,
            0xff4c4e4c,
            0xffe4e2e4,
            0xffc0c0c0, /* 背景色 */
            0xffc4c2c4,
            0xff7c7e7c,
            0xff2c2a2c,
            0xff9c9e9c,
            0xfffcfefc,
            0xff5c5e5c,
        };

        /** チェック（データ）*/
        static unsigned char checked_data[] = {
            0x4,0x4,0x4,0x4,0x7,0x0,0x0,0x7,0x4,0x4,0x4,0x4,
            0x4,0x4,0x7,0x0,0x2,0xa,0xa,0xa,0x2,0x0,0x4,0x4,
            0x4,0x7,0x2,0xa,0x6,0x6,0x6,0x1,0x1,0x8,0x0,0x4,
            0x4,0x0,0xa,0x6,0x0,0x0,0x0,0x0,0x8,0x8,0x2,0x4,
            0x7,0x2,0x6,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x5,0x2,
            0x0,0xa,0x6,0x0,0x0,0x0,0x0,0x0,0x0,0x5,0x5,0x0,
            0x0,0xa,0x6,0x0,0x0,0x0,0x0,0x0,0x0,0x5,0x3,0x0,
            0x7,0xa,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x9,0x2,
            0x4,0x7,0x1,0x8,0x0,0x0,0x0,0x0,0x3,0x9,0x2,0x4,
            0x4,0x7,0x8,0x8,0x8,0x5,0x5,0x3,0x9,0x9,0x0,0x4,
            0x4,0x4,0x7,0x2,0x5,0x5,0x3,0x9,0x2,0x0,0x4,0x4,
            0x4,0x4,0x4,0x4,0x2,0x0,0x0,0x2,0x4,0x4,0x4,0x4,
        };

        /** ラベルなしのチェックボックスを構築します。*/
        Checkbox::Checkbox() {
            addClassName(baygui_awt_Checkbox);
            this->state = false;
            this->group = NULL;
            this->label = NULL;
        }

        /** 指定されたラベルが付いたチェックボックスを構築します。*/
        Checkbox::Checkbox(const char* label) {
            addClassName(baygui_awt_Checkbox);
            this->state = false;
            this->group = NULL;
            setLabel(label);
        }

        /** デストラクタです。*/
        Checkbox::~Checkbox() {
            delete this->label;
        }

        /** チェックボックスのラベルを返します。*/
        char* Checkbox::getLabel() {
            return this->label;
        }

        /** このチェックボックスが「オン」の状態であるか、「オフ」の状態であるかを判定します。*/
        bool Checkbox::getState() {
            return this->state;
        }

        /** このコンポーネントをペイントします。*/
        void Checkbox::paint(Graphics* g) {
            int w = getWidth();
            int h = getHeight();

            /* 一度背景色でクリア */
            g->setColor(getBackground());
            g->fillRect(0, 0, w, h);

            /* 文字列を描画 */
            int fh = 12;
            int y = (h - fh) / 2;
            if (isEnabled() == true) {
                g->setColor(getForeground());
            } else {
                g->setColor(Color::gray);
            }
            g->drawString(getLabel(), 14, y);

            /* チェックを描画 */
            for (int i = 0; i < 12; i++) {
                for (int j = 0; j < 12; j++) {
                    /* チェックの周りは背景色で塗る */
                    unsigned int c = 0;
                    if (this->state == true) {
                        c = checked_palette[checked_data[i * 12 + j] & 0xFF];
                    } else {
                        c = unchecked_palette[unchecked_data[i * 12 + j] & 0xFF];
                    }
                    if (c == 0xffc0c0c0) {
                        g->setColor(getBackground());
                    } else {
                        g->setColor(c);
                    }
                    g->drawPixel(j + 0, i + y);
                }
            }
        }

        /** このコンポーネントで発生するマウスイベントを処理します。*/
        void Checkbox::processMouseEvent(MouseEvent* e) {
            Component::processMouseEvent(e);

            if (e->getID() == MouseEvent::MOUSE_PRESSED) {
                if (this->state == false) {
                    setState(true);
                }
            }
        }

        /** チェックボックスのラベルを、指定された文字列に設定します。*/
        void Checkbox::setLabel(const char* label) {
            if (this->label != NULL) delete this->label;
            int I = strlen(label) + 1;
            this->label = new char[I];
            memcpy(this->label, label, I);
        }

        /** このチェックボックスの状態を、指定された状態に設定します。*/
        void Checkbox::setState(bool state) {
            if (this->state == true && state == false) {
                this->state = false;
                repaint();
            } else if (this->state == false && state == true) {
                this->state = true;
                if (this->group != NULL) {
                    this->group->setSelectedCheckbox(this);
                }
                repaint();
            }
        }
    }
}
