# -*- coding: utf-8 -*-

# Copyright 2014-2016 Mir Calculate. http://www.calculate-linux.org
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

import curses
from os import environ, path
import os
import sys
import struct
import fcntl
import termios
from calculate.lib.utils.tools import Singleton, ignore


class Terminal(object):
    __metaclass__ = Singleton

    WRONG = -1

    def __init__(self):
        try:
            curses.setupterm(environ.get('TERM', 'linux'))
            self.curses = curses
        except curses.error:
            self.curses = None
        self.__echo = True
        self.__cursor = True

    @property
    def colors(self):
        if self.curses:
            return self.curses.tigetnum('colors')
        else:
            return 16

    @property
    def width(self):
        s = struct.pack("HHHH", 0, 0, 0, 0)
        fd_stdout = sys.stdout.fileno()
        try:
            x = fcntl.ioctl(fd_stdout, termios.TIOCGWINSZ, s)
        except IOError:
            # если ошибка то ширина 80 символов
            return -1
        # (rows, cols, x pixels, y pixels)
        return struct.unpack("HHHH", x)[1]

    @staticmethod
    def is_boot_console():
        stdout_file = '/proc/self/fd/0'
        if path.exists(stdout_file):
            return os.readlink(stdout_file) == '/dev/console'
        return False

    @property
    def echo(self):
        return self.__echo

    @echo.setter
    def echo(self, flag):
        fd = sys.stdin.fileno()
        with ignore(termios.error):
            old = termios.tcgetattr(fd)
            if flag:
                old[3] = old[3] | termios.ECHO
            else:
                old[3] &= ~termios.ECHO
            termios.tcsetattr(fd, termios.TCSADRAIN, old)
            self.__echo = flag

    @property
    def cursor(self):
        return self.__cursor

    @cursor.setter
    def cursor(self, flag):
        if self.curses:
            param = "cnorm" if flag else "civis"
            try:
                sys.stdout.write(self.curses.tigetstr(param))
                sys.stdout.flush()
            except TypeError:
                pass
            self.__cursor = flag
