# -*- coding: utf-8 -*-
# Elisa - Home multimedia server
# Copyright (C) 2006-2008 Fluendo Embedded S.L. (www.fluendo.com).
# All rights reserved.
#
# This file is available under one of two license agreements.
#
# This file is licensed under the GPL version 3.
# See "LICENSE.GPL" in the root of this distribution including a special
# exception to use Elisa with Fluendo's plugins.
#
# The GPL part of Elisa is also available under a commercial licensing
# agreement from Fluendo.
# See "LICENSE.Elisa" in the root directory of this distribution package
# for details on that license.

from elisa.core import common
from elisa.core.input_event import *
from elisa.base_components.controller import Controller

from raval_widgets import grid_bar

plugin_registry = common.application.plugin_registry
BaseListController = plugin_registry.get_component_class('raval:list_controller')

class GridController(BaseListController):

    min_lines = 1
    max_lines = 5
    lines = 3
    ratio = 7 / 3.
    grid_bar_index = grid_bar.NONE_FOCUSED
    old_grid_bar_index = grid_bar.NONE_FOCUSED

    def handle_input(self, input_event):
        if input_event.action == EventAction.GO_RIGHT:
            if self.grid_bar_index != grid_bar.NONE_FOCUSED:
                new_value = self.grid_bar_index + 1
                if new_value < grid_bar.ZOOM_IN_FOCUSED + 1:
                    self.grid_bar_index = new_value
            else:
                self.old_grid_bar_index = grid_bar.NONE_FOCUSED
                self.next_item(self.lines)
            return True
        
        elif input_event.action == EventAction.GO_LEFT:
            if self.grid_bar_index != grid_bar.NONE_FOCUSED:
                new_value = self.grid_bar_index - 1
                if new_value >= grid_bar.NONE_FOCUSED:
                    self.grid_bar_index = new_value
            else:
                self.old_grid_bar_index = grid_bar.NONE_FOCUSED
                self.previous_item(self.lines)
            return True
        
        elif input_event.action == EventAction.GO_UP:
            if self.grid_bar_index != grid_bar.NONE_FOCUSED:
                self.old_grid_bar_index = self.grid_bar_index
                self.grid_bar_index = grid_bar.NONE_FOCUSED
            else:
                line = self.current_index % self.lines
                if line-1 >= 0:
                    self.previous_item()
                else:
                    # Our Parent should take care of it
                    return False
            return True

        elif input_event.action == EventAction.GO_DOWN:
            line = self.current_index % self.lines
            if (line+1 >= len(self.model)) or  \
                        line+1 >= self.lines or \
                        self.current_index+1  >= len(self.model):
                # enter in grid bar
                self.go_to_grid()
            else:
                self.next_item()
            return True


        elif input_event.action == EventAction.NONE:
            # it is a simple other key:
            value = unicode(input_event.value)[-1:]
            try:
                # is it a usuabel for us
                idx = int(value)
            except ValueError:
                pass
            else:
                rows = len(self.model) / self.lines
                if (len(self.model) % self.lines):
                    rows += 1
                if rows <= 10:
                    # adress directly in a human friendly way
                    idx = max(0, idx-1)
                    if rows >= idx:
                        self.current_index = idx * self.lines
                    # or don't if to the value is too big
                else:
                    new_idx = int(rows / 10. * idx) * self.lines
                    self.current_index = new_idx

                return True

        else:
            return super(GridController, self).handle_input(input_event)

    def activate_item(self, origin):
        if self.grid_bar_index != grid_bar.NONE_FOCUSED:
            idx = self.grid_bar_index
            if idx == grid_bar.BACK_FOCUSED:
                self.parent.exit_node()
            elif idx == grid_bar.ZOOM_IN_FOCUSED:
                if self.lines > self.min_lines:
                    self.lines -= 1.
            elif idx == grid_bar.ZOOM_OUT_FOCUSED:
                if self.lines < self.max_lines:
                    self.lines += 1.
        else:
            super(GridController, self).activate_item(origin)

    def go_to_grid(self):
        if self.old_grid_bar_index != grid_bar.NONE_FOCUSED:
            self.grid_bar_index = self.old_grid_bar_index
        else:
            # calculate the last Item, we want the BACK_FOCUSED on:
            rows = round( self.ratio * self.lines / 2)  
            all_rows = round(len(self.model) / self.lines)
            last = (all_rows - rows + 1) * self.lines
            if self.current_index <= last:
                self.grid_bar_index = grid_bar.BACK_FOCUSED
            else:
                self.grid_bar_index = grid_bar.ZOOM_IN_FOCUSED
