/***************************************************************************
 *   crwx-ng                                                               *
 *   Copyright (C) 2007,2008,2010,2012 Vadim Lopatin <coolreader.org@gmail.com>
 *   Copyright (C) 2008 Torque <torque@mail.ru>                            *
 *   Copyright (C) 2018 Sergey Torokhov <torokhov-s-a@yandex.ru>           *
 *   Copyright (C) 2020,2021,2023,2024 Aleksey Chernov <valexlin@gmail.com>*
 *                                                                         *
 *   This program is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU General Public License           *
 *   as published by the Free Software Foundation; either version 2        *
 *   of the License, or (at your option) any later version.                *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the Free Software           *
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,            *
 *   MA 02110-1301, USA.                                                   *
 ***************************************************************************/

#include "readerframe.h"
#include "readerview.h"
#include "utils.h"
#include "optdlg.h"
#include "toc.h"
#include "readerscrollbar.h"
#include "wolopt.h"
#include "aboutdialog.h"
#include "histlist.h"
#include "rescont.h"
#include "app-props.h"
#include "config.h"

#include <wx/filedlg.h>
#include <wx/sizer.h>

#include <lvdocviewprops.h>

namespace resources
{
#include "cr3.xpm"
}

BEGIN_EVENT_TABLE(ReaderFrame, wxFrame)
    EVT_MENU(Menu_File_Quit, ReaderFrame::OnQuit)
    EVT_MENU(Menu_File_About, ReaderFrame::OnAbout)
    EVT_MENU(wxID_OPEN, ReaderFrame::OnFileOpen)
    EVT_MENU(Menu_File_Export, ReaderFrame::OnFileExport)
    EVT_MENU(Menu_View_TOC, ReaderFrame::OnShowTOC)
    EVT_MENU(Menu_File_Options, ReaderFrame::OnShowOptions)
    EVT_MENU(Menu_View_History, ReaderFrame::OnShowHistory)
    EVT_MENU(Menu_View_Rotate, ReaderFrame::OnRotate)
    EVT_MENU_RANGE(0, 0xFFFF, ReaderFrame::OnCommand)
    //EVT_UPDATE_UI_RANGE(0, 0xFFFF, cr3Frame::OnUpdateUI)
    EVT_COMMAND_SCROLL(Window_Id_Scrollbar, ReaderFrame::OnScroll)
    EVT_CLOSE(ReaderFrame::OnClose)
    EVT_MOUSEWHEEL(ReaderFrame::OnMouseWheel)
    EVT_INIT_DIALOG(ReaderFrame::OnInitDialog)
    EVT_LIST_ITEM_ACTIVATED(Window_Id_HistList, ReaderFrame::OnHistItemActivated)
    //EVT_SIZE(cr3Frame::OnSize)
END_EVENT_TABLE()

void ReaderFrame::OnUpdateUI(wxUpdateUIEvent& event) { }

void ReaderFrame::OnClose(wxCloseEvent& event) {
    SaveOptions();
    _view->CloseDocument();
    Destroy();
}

void ReaderFrame::OnHistItemActivated(wxListEvent& event) {
    long index = event.GetIndex();
    if (index == 0 && _view->getDocView()->isDocumentOpened()) {
        SetActiveMode(am_book);
        return;
    }
    if (index >= 0 && index < _view->getDocView()->getHistory()->getRecords().length()) {
        lString32 pathname = _view->getDocView()->getHistory()->getRecords()[index]->getFilePath() +
                             _view->getDocView()->getHistory()->getRecords()[index]->getFileName();
        if (!pathname.empty()) {
            Update();
            SetActiveMode(am_book);
            _view->LoadDocument(cr2wx(pathname));
            UpdateToolbar();
        }
    }
}

void ReaderFrame::OnCommand(wxCommandEvent& event) {
    _view->OnCommand(event);
    switch (event.GetId()) {
        case Menu_View_ToggleFullScreen:
            _isFullscreen = !_isFullscreen;
            _view->SetFullScreenState(_isFullscreen);
            ShowFullScreen(_isFullscreen);
            break;
        case Menu_View_ZoomIn:
        case Menu_View_ZoomOut:
            // Update props from view
            _props->setInt(PROP_FONT_SIZE, _view->getDocView()->getFontSize());
            break;
        case Menu_View_NextPage:
        case Menu_View_PrevPage:
        case Menu_Link_Forward:
        case Menu_Link_Back:
        case Menu_Link_Next:
        case Menu_Link_Prev:
        case Menu_Link_Go:
        case Menu_View_Text_Format:
            break;
    }
}

void ReaderFrame::OnMouseWheel(wxMouseEvent& event) {
    _view->OnMouseWheel(event);
}

void ReaderFrame::OnSize(wxSizeEvent& event) { }

wxBitmap ReaderFrame::getIcon(const lChar32* name) {
    wxLogNull logNo; // Temporary disable warnings ( see: http://trac.wxwidgets.org/ticket/15331 )
    lString32 dir;
    if (_toolbarSize == 2)
        dir = "icons/22x22/";
    else if (_toolbarSize == 1)
        dir = "icons/16x16/";
    else
        dir = "icons/32x32/";
    wxBitmap icon = ResourceContainer::instance().GetBitmap((dir + name + ".png").c_str());
    if (icon.IsOk())
        return icon;
    return wxNullBitmap;
} // ~wxLogNull called, old log sink restored

void ReaderFrame::UpdateToolbar() {
    if (_toolbarSize == 0)
        return;
    bool enabled_book = _activeMode == am_book && _view->getDocView()->isDocumentOpened();
    wxToolBar* toolBar = GetToolBar();
    toolBar->EnableTool(Menu_File_Export, enabled_book);
    toolBar->EnableTool(Menu_View_ZoomIn, enabled_book);
    toolBar->EnableTool(Menu_View_ZoomOut, enabled_book);
    toolBar->EnableTool(Menu_View_TOC, enabled_book);
    toolBar->EnableTool(Menu_View_Rotate, enabled_book);
    toolBar->EnableTool(Menu_View_TogglePages, enabled_book);
    toolBar->EnableTool(Menu_View_PrevPage, enabled_book);
    toolBar->EnableTool(Menu_View_NextPage, enabled_book);
}

void ReaderFrame::SetActiveMode(active_mode_t mode) {
    if (mode == _activeMode)
        return;
    switch (mode) {
        case am_book: {
            _sizer->Show(_view, true);
            _sizer->Show(_scrollBar, true);
            _sizer->Show(_hist, false);
            _sizer->Layout();
            _view->SetFocus();
        } break;
        case am_history: {
            _sizer->Show(_view, false);
            _sizer->Show(_scrollBar, false);
            _sizer->Show(_hist, true);
            _sizer->Layout();
            _view->getDocView()->savePosition();
            _hist->SetRecords(_view->getDocView()->getHistory()->getRecords());
            _sizer->Layout();
            _hist->SetFocus();
        } break;
        default:
            break;
    }
    _activeMode = mode;
    UpdateToolbar();
}

void ReaderFrame::SetMenu(bool visible) {
    bool was_visible = (GetMenuBar() != NULL);
    if (was_visible == visible)
        return;
    if (!visible) {
        SetMenuBar(NULL);
        return;
    }
    wxMenu* menuFile = new wxMenu;

    menuFile->Append(wxID_OPEN, wxT("&Open...\tCtrl+O"));
    menuFile->Append(Menu_View_History, wxT("Recent books list\tF4"));
    menuFile->Append(Menu_File_Export, wxT("&Export...\tCtrl+S"));
    menuFile->AppendSeparator();
    menuFile->Append(Menu_File_Options, wxT("&Options...\tF9"));
    menuFile->AppendSeparator();
    menuFile->Append(Menu_File_About, wxT("&About...\tF1"));
    menuFile->AppendSeparator();
    menuFile->Append(Menu_File_Quit, wxT("E&xit\tAlt+X"));

    wxMenu* menuView = new wxMenu;

    menuView->Append(Menu_View_TOC, wxT("Table of Contents\tF5"));
    menuView->Append(Menu_View_History, wxT("Recent Books\tF4"));
    menuView->Append(Menu_View_Rotate, wxT("Rotate\tCtrl+R"));

    menuView->AppendSeparator();
    menuView->Append(Menu_View_ZoomIn, wxT("Zoom In"));
    menuView->Append(Menu_View_ZoomOut, wxT("Zoom Out"));
    menuView->AppendSeparator();
    menuView->Append(Menu_View_ToggleFullScreen, wxT("Toggle Fullscreen\tAlt+Enter"));
    menuView->Append(Menu_View_TogglePages, wxT("Toggle Pages/Scroll\tCtrl+P"));
    menuView->Append(Menu_View_TogglePageHeader, wxT("Toggle page heading\tCtrl+H"));

    wxMenuBar* menuBar = new wxMenuBar;
    menuBar->Append(menuFile, wxT("&File"));
    menuBar->Append(menuView, wxT("&View"));

    SetMenuBar(menuBar);
}

void ReaderFrame::SetStatus(bool visible) {
    bool was_visible = (GetStatusBar() != NULL);
    if (was_visible == visible)
        return;
    if (!visible) {
        wxStatusBar* status = GetStatusBar();
        SetStatusBar(NULL);
        if (NULL != status)
            delete status;
        return;
    }
    wxStatusBar* status = CreateStatusBar();
    int sw[2] = { -1, 100 };
    //int ss[2] = { wxSB_NORMAL, wxSB_FLAT };
    status->SetFieldsCount(2, sw);
    //status->SetStatusStyles(3, ss);
}

static const long TOOLBAR_STYLE = wxTB_FLAT | wxTB_DOCKABLE; // | wxTB_TEXT // | wxTB_DOCKABLE

void ReaderFrame::SetToolbarSize(int size) {
    //if ( size == _toolbarSize )
    //    return;
    _toolbarSize = size;
    if (!_toolbarSize) {
        SetToolBar(NULL);
        return;
    }

    wxToolBar* toolBar = GetToolBar();

    long style = toolBar ? toolBar->GetWindowStyle() : TOOLBAR_STYLE;
    delete toolBar;
    SetToolBar(NULL);
    style &= ~(wxTB_HORIZONTAL | wxTB_VERTICAL | wxTB_BOTTOM | wxTB_RIGHT | wxTB_HORZ_LAYOUT);
    int mode = _props->getIntDef(PROP_APP_WINDOW_TOOLBAR_POSITION, 0);
    switch (mode) {
        case 1:
            style |= wxTB_LEFT;
            break;
        default:
            style |= wxTB_TOP;
            break;
        case 2:
            style |= wxTB_RIGHT;
            break;
        case 3:
            style |= wxTB_BOTTOM;
            break;
    }
    //style |= wxTB_NO_TOOLTIPS;
    toolBar = CreateToolBar(style, wxID_ANY);

    wxBitmap fileopenBitmap = getIcon(U"fileopen");
    int w = fileopenBitmap.GetWidth();
    int h = fileopenBitmap.GetHeight();
    toolBar->SetToolBitmapSize(wxSize(w, h));
    /*
    toolBar->AddTool(wxID_NEW, _T("New"),
                     toolBarBitmaps[Tool_new], wxNullBitmap, wxITEM_NORMAL,
                     _T("New file"), _T("This is help for new file tool"));
*/
    toolBar->AddTool(wxID_OPEN, _T("Open"),
                     fileopenBitmap, //toolBarBitmaps[Tool_open],
                     wxNullBitmap, wxITEM_NORMAL, _T("Open file"), _T("This is help for open file tool"));
    toolBar->AddTool(Menu_View_History, _T("History (F5)"),
                     getIcon(U"project_open"), //toolBarBitmaps[Tool_open],
                     wxNullBitmap, wxITEM_NORMAL, _T("Toggle recent books list"),
                     _T("Toggle recent opened books list"));

    toolBar->AddTool(Menu_File_Export, _T("Export"),
                     getIcon(U"filesaveas"), //toolBarBitmaps[Tool_save],
                     wxNullBitmap, wxITEM_NORMAL, _T("Export to..."), _T("Export document"));

    toolBar->AddSeparator();
    toolBar->AddTool(Menu_View_ZoomIn, _T("Zoom In"),
                     getIcon(U"viewmag+"), //toolBarBitmaps[Tool_zoomin],
                     wxNullBitmap, wxITEM_NORMAL, _T("Zoom in"), _T("Increase font size"));
    toolBar->AddTool(Menu_View_ZoomOut, _T("Zoom Out"),
                     getIcon(U"viewmag-"), //toolBarBitmaps[Tool_zoomout],
                     wxNullBitmap, wxITEM_NORMAL, _T("Zoom out"), _T("Decrease font size"));
    toolBar->AddTool(Menu_View_Rotate, _T("Rotate (Ctrl+R)"),
                     getIcon(U"rotate_cw"), //toolBarBitmaps[Tool_zoomout],
                     wxNullBitmap, wxITEM_NORMAL, _T("Rotate (Ctrl+R)"), _T("Rotate text clockwise"));
    toolBar->AddSeparator();
    toolBar->AddTool(Menu_View_TOC, _T("Table of Contents (F5)"),
                     getIcon(U"player_playlist"), //toolBarBitmaps[Tool_zoomout],
                     wxNullBitmap, wxITEM_NORMAL, _T("Table of Contents (F5)"), _T("Show Table of Contents window"));
    toolBar->AddTool(Menu_View_TogglePages, _T("Toggle pages (Ctrl+P)"),
                     getIcon(U"view_left_right"), //toolBarBitmaps[Tool_zoomout],
                     wxNullBitmap, wxITEM_NORMAL, _T("Toggle pages (Ctrl+P)"), _T("Switch pages/scroll mode"));
    toolBar->AddTool(Menu_View_ToggleFullScreen, _T("Fullscreen (Alt+Enter)"),
                     getIcon(U"window_fullscreen"), //toolBarBitmaps[Tool_zoomout],
                     wxNullBitmap, wxITEM_NORMAL, _T("Fullscreen (Alt+Enter)"), _T("Switch to fullscreen mode"));
    toolBar->AddSeparator();
    //Menu_View_ToggleFullScreen
    toolBar->AddTool(Menu_View_PrevPage, _T("Previous page"),
                     getIcon(U"previous"), //toolBarBitmaps[Tool_north],
                     wxNullBitmap, wxITEM_NORMAL, _T("Previous page"), _T("Go to previous page"));
    toolBar->AddTool(Menu_View_NextPage, _T("Next page"),
                     getIcon(U"next"), //toolBarBitmaps[Tool_south],
                     wxNullBitmap, wxITEM_NORMAL, _T("Next page"), _T("Go to next page"));

    toolBar->AddSeparator();
    toolBar->AddTool(Menu_File_Options, _T("Options"), //wxID_HELP
                     getIcon(U"configure"),            //toolBarBitmaps[Tool_help],
                     wxNullBitmap, wxITEM_NORMAL, _T("Options (F9)"), _T("Options (F9)"));
    toolBar->AddSeparator();
    toolBar->AddTool(Menu_File_About, _T("Help"), //wxID_HELP
                     getIcon(U"help"),            //toolBarBitmaps[Tool_help],
                     wxNullBitmap, wxITEM_NORMAL, _T("Help"), _T("Help"));

    // after adding the buttons to the toolbar, must call Realize() to reflect
    // the changes
    toolBar->Realize();
}

void ReaderFrame::OnInitDialog(wxInitDialogEvent& event) {
    _scrollBar = new ReaderScrollBar(_view);

    _view->SetScrollBar(_scrollBar);
    _view->Create(this, Window_Id_View, wxDefaultPosition, wxDefaultSize, 0, wxT("ReaderView"));
    _hist->Create(this, Window_Id_HistList);

    _scrollBar->Create(this, Window_Id_Scrollbar, wxDefaultPosition, wxDefaultSize, wxSB_VERTICAL);

    wxIcon icon = wxICON(resources::cr3);
    SetIcon(icon);

    _sizer = new wxBoxSizer(wxHORIZONTAL);
    _sizer->Add(_view, 1, wxALL | wxEXPAND, 0);
    _sizer->Add(_scrollBar, 0, wxEXPAND, 0);
    _sizer->Add(_hist, 1, wxALL | wxEXPAND, 0);

    SetSizer(_sizer);

    _view->SetBackgroundColour(_view->getBackgroundColour());
    //_scrollBar->Show( true );
    SetBackgroundColour(_view->getBackgroundColour());

    _view->loadCSS("fb2.css");

    wxAcceleratorEntry entries[40];
    int a = 0;
    entries[a++].Set(wxACCEL_CTRL, (int)'O', wxID_OPEN);
    entries[a++].Set(wxACCEL_CTRL, (int)'S', Menu_File_Export);
    entries[a++].Set(wxACCEL_CTRL, (int)'P', Menu_View_TogglePages);
    entries[a++].Set(wxACCEL_CTRL, (int)'H', Menu_View_TogglePageHeader);
    entries[a++].Set(wxACCEL_CTRL, (int)'R', Menu_View_Rotate);
    entries[a++].Set(wxACCEL_NORMAL, WXK_F3, wxID_OPEN);
    entries[a++].Set(wxACCEL_NORMAL, WXK_F2, Menu_File_Export);
    entries[a++].Set(wxACCEL_NORMAL, WXK_UP, Menu_View_PrevLine);
    entries[a++].Set(wxACCEL_NORMAL, WXK_DOWN, Menu_View_NextLine);
    entries[a++].Set(wxACCEL_NORMAL, WXK_SPACE, Menu_View_NextLine);
    entries[a++].Set(wxACCEL_NORMAL, WXK_NUMPAD_ADD, Menu_View_ZoomIn);
    entries[a++].Set(wxACCEL_NORMAL, WXK_NUMPAD_SUBTRACT, Menu_View_ZoomOut);
    entries[a++].Set(wxACCEL_NORMAL, WXK_ADD, Menu_View_ZoomIn);
    entries[a++].Set(wxACCEL_NORMAL, WXK_SUBTRACT, Menu_View_ZoomOut);
    entries[a++].Set(wxACCEL_CTRL, WXK_NUMPAD_ADD, Menu_View_ZoomIn);
    entries[a++].Set(wxACCEL_CTRL, WXK_NUMPAD_SUBTRACT, Menu_View_ZoomOut);
    entries[a++].Set(wxACCEL_NORMAL, (int)'+', Menu_View_ZoomIn);
    entries[a++].Set(wxACCEL_NORMAL, (int)'-', Menu_View_ZoomOut);
    entries[a++].Set(wxACCEL_NORMAL, (int)'=', Menu_View_ZoomIn);
    entries[a++].Set(wxACCEL_NORMAL, WXK_PAGEUP, Menu_View_PrevPage);
    entries[a++].Set(wxACCEL_NORMAL, WXK_PAGEDOWN, Menu_View_NextPage);
    entries[a++].Set(wxACCEL_NORMAL, WXK_HOME, Menu_View_Begin);
    entries[a++].Set(wxACCEL_NORMAL, WXK_END, Menu_View_End);
    entries[a++].Set(wxACCEL_CTRL, (int)'T', Menu_View_Text_Format);
    entries[a++].Set(wxACCEL_ALT, WXK_RETURN, Menu_View_ToggleFullScreen);
    entries[a++].Set(wxACCEL_NORMAL, WXK_F5, Menu_View_TOC);
    entries[a++].Set(wxACCEL_NORMAL, WXK_F4, Menu_View_History);

    entries[a++].Set(wxACCEL_NORMAL, WXK_F9, Menu_File_Options);
    entries[a++].Set(wxACCEL_NORMAL, WXK_F12, Menu_File_Quit);
    entries[a++].Set(wxACCEL_NORMAL, WXK_BACK, Menu_Link_Back);
    entries[a++].Set(wxACCEL_SHIFT, WXK_BACK, Menu_Link_Forward);
    entries[a++].Set(wxACCEL_NORMAL, WXK_TAB, Menu_Link_Next);
    entries[a++].Set(wxACCEL_NORMAL, WXK_RETURN, Menu_Link_Go);
    entries[a++].Set(wxACCEL_SHIFT, WXK_TAB, Menu_Link_Prev);

    wxAcceleratorTable accel(a, entries);
    SetAcceleratorTable(accel);
    //_view->SetAcceleratorTable(accel);

    //toolBar->SetRows(!(toolBar->IsVertical()) ? m_rows : 10 / m_rows);
    wxString fnameToOpen = _fnameToOpen;
    if (fnameToOpen.empty())
        fnameToOpen = cr2wx(_view->GetLastRecentFileName());

    _view->Show(true);
    //_view->UpdateScrollBar();

    RestoreOptions();
    if (!fnameToOpen.empty()) {
        if (!_view->LoadDocument(fnameToOpen)) {
            CRLog::error("cannot open document");
        }
        SetActiveMode(am_book);
        UpdateToolbar();
    } else {
        SetActiveMode(am_history);
    }
}

ReaderFrame::ReaderFrame(const wxString& title, const wxString& fnameToOpen, const wxPoint& p, const wxSize& sz)
        : wxFrame((wxFrame*)NULL, -1, title, p, sz)
        , _activeMode(am_none)
        , _toolbarSize(false)
        , _fnameToOpen(fnameToOpen) {
    _props = LVCreatePropsContainer();
    _isFullscreen = false;
    {
        // load options from file
        lString32 inifile = getConfigDir() + cs32("crwx.ini");
        LVStreamRef stream = LVOpenFileStream(inifile.c_str(), LVOM_READ);
        if (!stream.isNull())
            _props->loadFromStream(stream.get());
    }
    addDefaultsSettingsIfOmitted();
    _view = new ReaderView(_props);
    _hist = new HistList();
    InitDialog();
}

void ReaderFrame::SaveOptions() {
    //_props->setHex(PROP_FONT_COLOR, _view->getDocView()->getTextColor() );
    //_props->setHex(PROP_BACKGROUND_COLOR, _view->getDocView()->getBackgroundColor() );
    //_props->setInt(PROP_FONT_SIZE, _view->getDocView()->getFontSize());
    _props->setBool(PROP_APP_WINDOW_FULLSCREEN, _isFullscreen);
    bool maximized = IsMaximized();
    bool minimized = IsIconized();
    _props->setBool(PROP_APP_WINDOW_MAXIMIZED, maximized);
    _props->setBool(PROP_APP_WINDOW_MINIMIZED, minimized);
    if (!minimized && !maximized && !_isFullscreen) {
        wxRect rc = GetRect();
        // In lvRect 'right' is smallest coordinate that is outside the right border of the rectangle
        // In lvRect 'bottom' is smallest coordinate that is outside the bottom border of the rectangle
        lvRect lvrc(rc.GetLeft(), rc.GetTop(), rc.GetRight() + 1, rc.GetBottom() + 1);
        _props->setRect(PROP_APP_WINDOW_RECT, lvrc);
    }
    {
        // save options to file
        lString32 inifile = getConfigDir() + cs32("crwx.ini");
        LVStreamRef stream = LVOpenFileStream(inifile.c_str(), LVOM_WRITE);
        if (!stream.isNull())
            _props->saveToStream(stream.get());
    }
}

void ReaderFrame::RestoreOptions() {
    if (!_isFullscreen) {
        SetMenu(_props->getBoolDef(PROP_APP_WINDOW_SHOW_MENU, true));
        SetStatus(_props->getBoolDef(PROP_APP_WINDOW_SHOW_STATUSBAR, true));
        int tb = _props->getIntDef(PROP_APP_WINDOW_TOOLBAR_SIZE, 2);
        if (tb < 0)
            tb = 0;
        if (tb > 3)
            tb = 3;
        SetToolbarSize(tb);
        lvRect lvrc;
        if (_props->getRect(PROP_APP_WINDOW_RECT, lvrc)) {
            wxRect rc(lvrc.left, lvrc.top, lvrc.width(), lvrc.height());
            SetSize(rc);
        }
        if (_props->getBoolDef(PROP_APP_WINDOW_MAXIMIZED))
            Maximize();
        else if (_props->getBoolDef(PROP_APP_WINDOW_MINIMIZED))
            Iconize();
    }
    _view->ApplyProps();

    if (_props->getBoolDef(PROP_APP_WINDOW_FULLSCREEN) != _isFullscreen) {
        _isFullscreen = !_isFullscreen;
        if (_isFullscreen)
            Show();
        ShowFullScreen(_isFullscreen);
    }
}

void ReaderFrame::addDefaultsSettingsIfOmitted() {
    _props->setIntDef(PROP_APP_PAGE_VIEW_MODE, 2);
    _props->setBoolDef(PROP_TEXTLANG_EMBEDDED_LANGS_ENABLED, true);
    _props->setBoolDef(PROP_TEXTLANG_HYPHENATION_ENABLED, true);
}

void ReaderFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) {
    //SaveOptions();
    Close(TRUE);
}

void ReaderFrame::OnShowHistory(wxCommandEvent& event) {
    switch (_activeMode) {
        case am_book:
            SetActiveMode(am_history);
            break;
        case am_history:
            SetActiveMode(am_book);
            break;
        default:
            break;
    }
}

void ReaderFrame::OnOptionsChange(CRPropRef oldprops, CRPropRef newprops, CRPropRef changed) {
    if (changed->getCount() > 0) {
        _props->set(newprops);
        SaveOptions();
        RestoreOptions();
    }
    ///
}

void ReaderFrame::OnShowOptions(wxCommandEvent& event) {
    CR3OptionsDialog dlg(_props);
    dlg.Create(this, Window_Id_Options);
    if (dlg.ShowModal() == wxID_OK) {
        // set options
        dlg.ControlsToProps();
        OnOptionsChange(dlg.getOldProps(), dlg.getNewProps(), dlg.getChangedProps());
    }
}

void ReaderFrame::OnRotate(wxCommandEvent& event) {
    _view->Rotate();
    SaveOptions();
}

void ReaderFrame::OnShowTOC(wxCommandEvent& event) {
    LVTocItem* toc = _view->getDocView()->getToc();
    ldomXPointer pos = _view->getDocView()->getBookmark();
    if (!toc || !toc->getChildCount())
        return;
    TocDialog dlg(this, toc, _view->getDocView()->getTitle(), pos);
    if (dlg.ShowModal() == wxID_OK) {
        // go to
        LVTocItem* sel = dlg.getSelection();
        if (sel) {
            ldomXPointer ptr = sel->getXPointer();
            _view->goToBookmark(ptr);
            Update();
        }
    }
}

void ReaderFrame::OnFileOpen(wxCommandEvent& WXUNUSED(event)) {
    wxString all_fmt_flt =
#if (USE_CHM == 1) && ((USE_CMARK == 1) || (USE_CMARK_GFM == 1))
            wxT("*.fb2;*.fb3;*.txt;*.tcr;*.rtf;*.odt;*.doc;*.docx;*.epub;*.html;*.shtml;*.htm;*.md;*.chm;*.zip;*.pdb;*.pml;*.prc;*.pml;*.mobi");
#elif (USE_CHM == 1)
            wxT("*.fb2;*.fb3;*.txt;*.tcr;*.rtf;*.odt;*.doc;*.docx;*.epub;*.html;*.shtml;*.htm;*.chm;*.zip;*.pdb;*.pml;*.prc;*.pml;*.mobi");
#else
            wxT("*.fb2;*.fb3;*.txt;*.tcr;*.rtf;*.odt;*.doc;*.docx;*.epub;*.html;*.shtml;*.htm;*.zip;*.pdb;*.pml;*.prc;*.pml;*.mobi");
#endif
    wxFileDialog dlg(this, wxT("Choose a file to open"), wxT(""),
                     wxT(""), //const wxString& defaultFile = "",
                     wxT("All supported files|") + all_fmt_flt + wxT("|") +
                             wxT("FictionBook files (*.fb2)|*.fb2;*.fbz;*.fb2.zip|") + wxT("FB3 files (*.fb3)|*.fb3|") +
                             wxT("Text files (*.txt, *.tcr)|*.txt;*.tcr|") + wxT("Rich text (*.rtf)|*.rtf|") +
                             wxT("MS Word document (*.doc, *.docx)|*.doc;*.docx|") +
                             wxT("Open Document files (*.odt)|*.odt|") +
                             wxT("HTML files (*.html, *.htm, *.shtml, *.xhtml)|*.html;*.htm;*.shtml;*.xhtml|") +
#if (USE_CMARK == 1) || (USE_CMARK_GFM == 1)
                             wxT("Markdown files (*.md)|*.md|") +
#endif
                             wxT("EPUB files (*.epub)|*.epub|") +
#if USE_CHM == 1
                             wxT("CHM files (*.chm)|*.chm|") +
#endif
                             wxT("MOBI files (*.mobi, *.prc, *.azw)|*.mobi;*.prc;*.azw|") +
                             wxT("PalmDOC files (*.pdb, *.pml)|*.pdb;*.pml|") + wxT("ZIP archives (*.zip)|*.zip"),
                     wxFD_OPEN | wxFD_FILE_MUST_EXIST //long style = wxFD_DEFAULT_STYLE,
    );
    if (dlg.ShowModal() == wxID_OK) {
        Update();
        SetActiveMode(am_book);
        wxCursor hg(wxCURSOR_WAIT);
        this->SetCursor(hg);
        wxSetCursor(hg);
        _view->getDocView()->savePosition();
        _view->LoadDocument(dlg.GetPath());
        Refresh();
        Update();
        UpdateToolbar();
        wxSetCursor(wxNullCursor);
        this->SetCursor(wxNullCursor);
    }
}

void ReaderFrame::OnFileExport(wxCommandEvent& WXUNUSED(event)) {
    wxFileDialog dlg(this, wxT("Choose a file to open"), wxT(""),
                     wxT(""),                               //const wxString& defaultFile = "",
                     wxT("Wolf EBook files (*.wol)|*.wol"), //const wxString& wildcard = "*.*",
                     wxFD_SAVE | wxFD_OVERWRITE_PROMPT      //long style = wxFD_DEFAULT_STYLE,
    );
    WolOptions opts(this);
    if (dlg.ShowModal() == wxID_OK && opts.ShowModal() == wxID_OK) {
        Refresh();
        Update();
        wxCursor hg(wxCURSOR_WAIT);
        this->SetCursor(hg);
        wxSetCursor(hg);
        _view->getDocView()->exportWolFile(wx2cr(dlg.GetPath()).c_str(), opts.getMode() == 0, opts.getLevels());
        wxSetCursor(wxNullCursor);
        this->SetCursor(wxNullCursor);
    }
}

void ReaderFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) {
    AboutDialog opts(this);
    opts.ShowModal();
}

void ReaderFrame::OnScroll(wxScrollEvent& event) {
    _view->OnScroll(event);
}

void ReaderFrame::OnKeyDown(wxKeyEvent& event) {
    if (_activeMode == am_book)
        _view->OnKeyDown(event);
    else
        event.Skip();
}
