#include "DmGreeterHelper.h"

#include "config.h"
#include "Common.h"
#include "UserSelectView.h"


#define DIRECTOR_ICON_WIDTH (32)
#define DIRECTOR_ICON_HEIGHT (90)
#define DEFAULT_AUTO_SELECT_USER_INTERVAL (500)

UserSelectView::UserSelectView()
    : Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0)
    , m_mainLyt(Gtk::ORIENTATION_HORIZONTAL, 0)
    , m_dirLeftContent(Gtk::ORIENTATION_HORIZONTAL, 0)
    , m_dirRightContent(Gtk::ORIENTATION_HORIZONTAL, 0)
    , m_userArea(Gtk::ORIENTATION_HORIZONTAL, 0)
    , m_dirLeftImg(GLOBAL_RES_DIR"/icon/dir-left.png")
    , m_dirRightImg(GLOBAL_RES_DIR"/icon/dir-right.png")
    , m_curFirstItemIndex(0)
    , m_userlist(DmGreeterHelper::inst()->getUserNameList())
    , m_scaleX(1.0f)
    , m_scaleY(1.0f) {

    Common::getPrimaryScaleFactors(m_scaleX, m_scaleY);

    m_dirLeft.add(m_dirLeftImg);
    m_dirRight.add(m_dirRightImg);

    m_dirLeft.set_name("dir_left");
    m_dirRight.set_name("dir_right");

    m_dirLeft.set_relief(Gtk::RELIEF_NONE);
    m_dirRight.set_relief(Gtk::RELIEF_NONE);

    m_sigLeftBtnPressIter = m_dirLeft.signal_clicked().connect(sigc::mem_fun(*this, &UserSelectView::onLeftClicked));
    m_sigRightBtnPressIter = m_dirRight.signal_clicked().connect(sigc::mem_fun(*this, &UserSelectView::onRightClicked));

    m_dirLeftContent.set_valign(Gtk::ALIGN_CENTER);
    m_dirRightContent.set_valign(Gtk::ALIGN_CENTER);

    m_dirLeftContent.pack_start(m_dirLeft, false, false, 0);
    m_dirRightContent.pack_start(m_dirRight, false, false, 0);

    for (int i = 0; i < USER_ITEMS_PER_PAGE_MAX; ++i) {
    	    m_userItemPerPage[i] = NULL;
    }

    m_mainLyt.set_halign(Gtk::ALIGN_CENTER);
    m_mainLyt.pack_start(m_dirLeftContent, false, false, 0);
    m_mainLyt.pack_start(m_userArea, false, false, 0);
    m_mainLyt.pack_start(m_dirRightContent, false, false, 0);
    
    pack_start(m_mainLyt, false, false, 0);

    loadUsers();

    set_can_focus(false);
}

UserSelectView::~UserSelectView() {
    for (int i = 0; i < USER_ITEMS_PER_PAGE_MAX; ++i) {
        if (NULL != m_userItemPerPage[i]) {
            delete m_userItemPerPage[i];
            m_userItemPerPage[i] = NULL;
        }
    }
    m_sigRightBtnPressIter.disconnect();
    m_sigLeftBtnPressIter.disconnect();
    m_sigUserItemPressIter.disconnect();
}

void UserSelectView::prePage() {
    if (m_dirLeft.is_visible() && m_dirRight.is_visible()) {
        onLeftClicked();
    }
}

void UserSelectView::nextPage() {
    if (m_dirLeft.is_visible() && m_dirRight.is_visible()) {
        onRightClicked();
    }
}

void UserSelectView::selectUserByNum(int userNum) {
    int userindex = userNum - 1;
    if (0 <= userindex && m_userItemPerPage.size() > userindex) {
        if (NULL != m_userItemPerPage[userindex]) {
            signalUserItemPress().emit(m_userItemPerPage[userindex]->getUserName());
        }
    }
}

sigc::signal<void, Glib::ustring> UserSelectView::signalUserItemPress() {
	return m_pressSignal;
}

void UserSelectView::resetFocus() {
    m_userItemPerPage[0]->resetFocus();
}

void UserSelectView::on_show() {
    Gtk::Box::on_show();
    if (USER_ITEMS_PER_PAGE_MAX < DmGreeterHelper::inst()->getUserCount()) {
        m_dirLeft.show();
        m_dirRight.show();
    } else {
        m_dirLeft.hide();
        m_dirRight.hide();
    }
}

void UserSelectView::loadUsers() {
    int userListLength = DmGreeterHelper::inst()->getUserCount();
    int itemCount = MIN(USER_ITEMS_PER_PAGE_MAX, userListLength);
    // if (2 >= itemCount) {
    //     Glib::RefPtr<Glib::TimeoutSource> tsource = Glib::TimeoutSource::create(DEFAULT_AUTO_SELECT_USER_INTERVAL);
    //     tsource->connect(sigc::mem_fun(*this, &UserSelectView::autoSelectUser));
    //     tsource->attach();
    // }
    if (userListLength > USER_ITEMS_PER_PAGE_MAX) {
    	    if (userListLength <= itemCount + m_curFirstItemIndex) {
            m_dirRight.set_sensitive(false);
	    } else {
            m_dirRight.set_sensitive(true);
	    }

        if (0 >= m_curFirstItemIndex) {
            m_dirLeft.set_sensitive(false);
        } else {
        	   m_dirLeft.set_sensitive(true);
        }
    } else {
        m_dirLeft.set_sensitive(false);
        m_dirRight.set_sensitive(false);
    }

    for (int i = 0; i < itemCount; ++i) {
        Glib::ustring userName = m_userlist[i + m_curFirstItemIndex];

        if (NULL == m_userItemPerPage[i]) {
            m_userItemPerPage[i] = new UserItem();
            m_sigUserItemPressIter = m_userItemPerPage[i]->signalUserItemPress().connect(sigc::mem_fun(*this, &UserSelectView::onUserPress));
            m_userArea.pack_start(*m_userItemPerPage[i], false, false, 0);
            m_userItemPerPage[i]->set_margin_left((int)(45 * m_scaleX));
            m_userItemPerPage[i]->set_margin_right((int)(45 * m_scaleX));
        }
        m_userItemPerPage[i]->setUserName(userName);
        if (!userName.empty()) {
            m_userItemPerPage[i]->setLoggedIn(DmGreeterHelper::inst()->isUserLoggedIn(userName));
        } else {
            m_userItemPerPage[i]->setLoggedIn(false);
        }
    }
}

void UserSelectView::onUserPress(Glib::ustring userName) {
    signalUserItemPress().emit(userName);
}

void UserSelectView::onLeftClicked() {
    m_curFirstItemIndex -= USER_ITEMS_PER_PAGE_MAX;
    if (0 > m_curFirstItemIndex) {
        m_curFirstItemIndex = 0;
    }
    loadUsers();
}

void UserSelectView::onRightClicked() {
    m_curFirstItemIndex += USER_ITEMS_PER_PAGE_MAX;
    int userListLength = DmGreeterHelper::inst()->getUserCount();
    if ((userListLength - USER_ITEMS_PER_PAGE_MAX) <= m_curFirstItemIndex) {
        m_curFirstItemIndex = userListLength - USER_ITEMS_PER_PAGE_MAX;
    }
    loadUsers();
}

bool UserSelectView::autoSelectUser() {
    int userListLength = DmGreeterHelper::inst()->getUserCount();
    int itemCount = MIN(USER_ITEMS_PER_PAGE_MAX, userListLength);
    selectUserByNum(itemCount);
    return false;
}