/*
    3D C++ Toolkit (TDT)
    Application Class
    Copyright (c) 2008
    John Ryland
*/
#include <TDT/application.h>
#include <TDT/widget.h>
#include <GLUT/glut.h>


using namespace TDT;


Widget::Widget(Widget *parent)
{
    mParent = parent;
    if ( parent )
        mWindow = parent->mWindow;
    else
        mWindow = new Window;
    mX = 0;
    mY = 0;
    mWidth = 10;
    mHeight = 10;
}


Widget::~Widget()
{
    if ( !mParent )
        delete mWindow;
    // delete children
}


void Widget::move(int x, int y)
{
    mX = x;
    mY = y;
    if ( !mParent )
        mWindow->move(x, y);
}


void Widget::resize(int width, int height)
{
    mWidth = width;
    mHeight = height;
    if ( !mParent )
        mWindow->resize(width, height);
}


void Widget::setGeometry(int x, int y, int width, int height)
{
    resize(width, height);
    move(x, y);
}


void Widget::show()
{
    setVisible(true);
}


void Widget::hide()
{
    setVisible(false);
}


void Widget::setVisible(bool visible)
{
    if ( visible == mVisible )
        return;
    mVisible = visible;
    if ( !mParent )
        mWindow->setVisible(visible);
}


void Widget::repaint()
{
    if ( !mParent )
        mWindow->repaint();
    else
        paintEvent();
}


void Widget::setCursor(int cursor)
{
    mCursor = cursor;
}


bool Widget::event(Event ev)
{
    switch (ev.type()) {
		case Event::Paint:
            paintEvent();
			break;
		case Event::Show:
            showEvent();
			break;
		case Event::Hide:
            hideEvent();
			break;
		case Event::Close:
            glutDestroyWindow(winId());
            closeEvent();
			break;
		case Event::Resize:
            mX = glutGet(GLUT_WINDOW_X);
            mY = glutGet(GLUT_WINDOW_Y);
            mWidth = ev.width();
            mHeight = ev.height();
            resizeEvent(ev.width(), ev.height());
			break;
		case Event::KeyPress:
            keyPressEvent(ev.key(), ev.x(), ev.y());
			break;
		case Event::KeyRelease:
            keyReleaseEvent(ev.key(), ev.x(), ev.y());
			break;
		case Event::MousePress:
            mousePressEvent(ev.button(), ev.x(), ev.y());
			break;
		case Event::MouseRelease:
            mouseReleaseEvent(ev.button(), ev.x(), ev.y());
			break;
		case Event::MouseMove:
            mouseMoveEvent(ev.x(), ev.y());
			break;
		case Event::FocusIn:
            focusInEvent();
			break;
		case Event::FocusOut:
            focusOutEvent();
			break;
		case Event::Idle:
            idleEvent();
			break;
		case Event::Timer:
            timerEvent(ev.timerId());
			break;
		case Event::OverlayDisplay:
            overlayDisplayedEvent();
			break;
        default:
            return false;
    }
    return true;
}


void Widget::paintEvent()
{
    glutSwapBuffers();
}


void Widget::showEvent()
{
}


void Widget::hideEvent()
{
}


void Widget::closeEvent()
{
}


void Widget::moveEvent(int x, int y)
{
}


void Widget::resizeEvent(int width, int height)
{
}


void Widget::keyPressEvent(int key, int x, int y)
{
}


void Widget::keyReleaseEvent(int key, int x, int y)
{
}


void Widget::mousePressEvent(int button, int x, int y)
{
}


void Widget::mouseReleaseEvent(int button, int x, int y)
{
}


void Widget::mouseMoveEvent(int x, int y)
{
}


void Widget::focusInEvent()
{
}


void Widget::focusOutEvent()
{
}


void Widget::idleEvent()
{
}


void Widget::timerEvent(int timerId)
{
}


void Widget::overlayDisplayedEvent()
{
}


