from anki.hooks import addHook
from aqt import mw

from ir.util import addMenuItem, addShortcut, viewingIrText


class ViewManager():
    def __init__(self):
        self.previousState = None
        addHook('afterStateChange', self.resetZoom)
        mw.web.page().scrollPositionChanged.connect(self.saveScroll)

    def addMenuItems(self):
        addMenuItem('Read', 'Zoom In', self.zoomIn, 'Ctrl++')
        addMenuItem('Read', 'Zoom Out', self.zoomOut, 'Ctrl+-')

    def addShortcuts(self):
        addShortcut(self.lineUp, 'Up')
        addShortcut(self.lineDown, 'Down')
        addShortcut(self.pageUp, 'PgUp')
        addShortcut(self.pageDown, 'PgDown')
        addShortcut(self.zoomIn, 'Ctrl+=')

    def setZoom(self, factor=None):
        if factor:
            mw.web.setZoomFactor(factor)
        else:
            mw.web.setZoomFactor(
                self.settings['zoom'][str(mw.reviewer.card.id)])

    def zoomIn(self):
        if viewingIrText():
            cid = str(mw.reviewer.card.id)

            if cid not in self.settings['zoom']:
                self.settings['zoom'][cid] = 1

            self.settings['zoom'][cid] += self.settings['zoomStep']
            mw.web.setZoomFactor(self.settings['zoom'][cid])
        elif mw.reviewer.card:
            newFactor = mw.web.zoomFactor() + self.settings['zoomStep']
            mw.web.setZoomFactor(newFactor)

    def zoomOut(self):
        if viewingIrText():
            cid = str(mw.reviewer.card.id)

            if cid not in self.settings['zoom']:
                self.settings['zoom'][cid] = 1

            self.settings['zoom'][cid] -= self.settings['zoomStep']
            mw.web.setZoomFactor(self.settings['zoom'][cid])
        elif mw.reviewer.card:
            newFactor = mw.web.zoomFactor() - self.settings['zoomStep']
            mw.web.setZoomFactor(newFactor)

    def setScroll(self, pos=None):
        if pos is None:
            savedPos = self.settings['scroll'][str(mw.reviewer.card.id)]
            mw.web.eval('window.scrollTo(0, {});'.format(savedPos))
        else:
            mw.web.eval('window.scrollTo(0, {});'.format(pos))
            self.saveScroll()

    def saveScroll(self, event=None):
        if viewingIrText():
            def callback(currentPos):
                self.settings['scroll'][str(mw.reviewer.card.id)] = currentPos

            mw.web.evalWithCallback('window.pageYOffset;', callback)

    def pageUp(self):
        currentPos = self.settings['scroll'][str(mw.reviewer.card.id)]
        movementSize = self.viewportHeight * self.settings['pageScrollFactor']
        newPos = max(0, (currentPos - movementSize))
        self.setScroll(newPos)

    def pageDown(self):
        currentPos = self.settings['scroll'][str(mw.reviewer.card.id)]
        movementSize = self.viewportHeight * self.settings['pageScrollFactor']
        newPos = min(self.pageBottom, (currentPos + movementSize))
        self.setScroll(newPos)

    def lineUp(self):
        currentPos = self.settings['scroll'][str(mw.reviewer.card.id)]
        movementSize = self.viewportHeight * self.settings['lineScrollFactor']
        newPos = max(0, (currentPos - movementSize))
        self.setScroll(newPos)

    def lineDown(self):
        currentPos = self.settings['scroll'][str(mw.reviewer.card.id)]
        movementSize = self.viewportHeight * self.settings['lineScrollFactor']
        newPos = min(self.pageBottom, (currentPos + movementSize))
        self.setScroll(newPos)

    def resetZoom(self, state, *args):
        if state in ['deckBrowser', 'overview']:
            mw.web.setZoomFactor(self.settings['generalZoom'])
        elif (state == 'review' and
              self.previousState != 'review' and
              mw.reviewer.card and
              (mw.reviewer.card.note().model()['name'] !=
               self.settings['modelName'])):
            self.setZoom(1)

        self.previousState = state

@@ -1853,316 +1853,8 @@
 r)%0A%0A
-    def setScroll(self, pos=None):%0A        if pos is None:%0A            savedPos = self.settings%5B'scroll'%5D%5Bstr(mw.reviewer.card.id)%5D%0A            mw.web.eval('window.scrollTo(0, %7B%7D);'.format(savedPos))%0A        else:%0A            mw.web.eval('window.scrollTo(0, %7B%7D);'.format(pos))%0A            self.saveScroll()%0A%0A
     
@@ -1879,32 +1879,32 @@
 f, event=None):%0A
+
         if viewi
@@ -2336,38 +2336,68 @@
         
-self.setScroll
+mw.web.eval('window.scrollTo(0, %7B%7D);'.format
 (newPos)
 %0A%0A    de
@@ -2380,32 +2380,33 @@
 '.format(newPos)
+)
 %0A%0A    def pageDo
@@ -2640,38 +2640,68 @@
         
-self.setScroll
+mw.web.eval('window.scrollTo(0, %7B%7D);'.format
 (newPos)
 %0A%0A    de
@@ -2684,32 +2684,33 @@
 '.format(newPos)
+)
 %0A%0A    def lineUp
@@ -2928,38 +2928,68 @@
         
-self.setScroll
+mw.web.eval('window.scrollTo(0, %7B%7D);'.format
 (newPos)
 %0A%0A    de
@@ -2972,32 +2972,33 @@
 '.format(newPos)
+)
 %0A%0A    def lineDo
@@ -3236,30 +3236,60 @@
     
-self.setScroll
+mw.web.eval('window.scrollTo(0, %7B%7D);'.format
 (newPos)
 %0A%0A  
@@ -3284,16 +3284,17 @@
 (newPos)
+)
 %0A%0A    de

Remove unneeded scroll restoration code