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

# Copyright 2008-2010 Calculate Ltd. 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 sys, struct, termios, fcntl
from cl_utils import _toUNICODE
import cl_overriding

class color_print(object):
    _printSysOut = sys.stdout

    def getconsolewidth(self):
        """Получить ширину текущей консоли"""
        s = struct.pack("HHHH", 0, 0, 0, 0)
        fd_stdout = self._printSysOut.fileno()
        try:
            x = fcntl.ioctl(fd_stdout, termios.TIOCGWINSZ, s)
        except IOError:
            # если ошибка то ширина 80 символов
            return 80
        #(rows, cols, x pixels, y pixels)
        return struct.unpack("HHHH", x)[1]

    def printRight(self, offsetLeft, offsetRight):
        """Добавляет необходимое количество пробелов:

        количество пробелов = (ширина консоли - offsetLeft - offsetRight)
        """
        cols = self.getconsolewidth()
        for i in range(cols - offsetLeft - offsetRight):
            self._printSysOut.write(" ")

    def colorPrint(self,attr,fg,bg,string):
        """Раскрашивает выводимое сообщение

        Параметры:
            attr - это атрибут
            fg - цвет символа
            bg - цвет фона

        в случае если параметр равен "" то он не изменяется

        attr может принимать следующие значения:
        0       сбросить все атрибуты (вернуться в нормальный режим)
        1       яркий (обычно включает толстый шрифт)
        2       тусклый
        3       подчёркнутый
        5       мигающий
        7       реверсный
        8       невидимый

        fg может принимать следующие значения:
        30      чёрный
        31      красный
        32      зелёный
        33      жёлтый
        34      синий
        35      фиолетовый
        36      голубой
        37      белый

        bg может принимать следующие значения:
        40      чёрный
        41      красный
        42      зелёный
        43      жёлтый
        44      синий
        45      фиолетовый
        46      голубой
        47      белый
        """
        lst = []
        if attr:
            lst.append(attr)
        if fg:
            lst.append(fg)
        if bg:
            lst.append(bg)
        self._printSysOut.write("\033[%sm%s\033[0m" %(";".join(lst),string))

    def redBrightPrint(self, string):
        """Печатает яркое красное сообщение"""
        self.colorPrint("1","31","",string)

    def greenBrightPrint(self, string):
        """Печатает яркое зеленое сообщение"""
        self.colorPrint("1","32","",string)

    def yellowBrightPrint(self, string):
        """Печатает яркое желтое сообщение"""
        self.colorPrint("1","33","",string)

    def blueBrightPrint(self, string):
        """Печатает яркое cинее сообщение"""
        self.colorPrint("1","34","",string)

    def lenString(self, string):
        """Получаем длинну строки"""
        stringUnicode = _toUNICODE(string)
        lenString = len(stringUnicode)
        return lenString


    def defaultPrint(self, string):
        self._printSysOut.write(string)
        try:
            self._printSysOut.flush()
        except IOError:
            cl_overriding.exit(1)

    def printLine(self, argL, argR, offsetL=0, printBR=True):
        """Печатает справа и слева консоли цветные сообщения"""
        #Допустимые цвета
        colorDict = {\
                 # цвет по умолчанию
                 '':self.defaultPrint,
                 # ярко зеленый
                 'greenBr':self.greenBrightPrint,
                 # ярко голубой
                 'blueBr':self.blueBrightPrint,
                 # ярко красный
                 'redBr':self.redBrightPrint,
                 # ярко желтый
                 'yellowBr':self.yellowBrightPrint,
        }
        # cмещение от левого края консоли
        #offsetL = 0
        for color,leftString in argL:
            offsetL += self.lenString(leftString)
            if colorDict.has_key(color):
                # печатаем и считаем смещение
                colorDict[color](leftString)
            else:
                colorDict[''](leftString)
        # cмещение от правого края консоли
        offsetR = 0
        for color,rightString in argR:
            offsetR += self.lenString(rightString)
        # Добавляем пробелы
        if offsetR:
            self.printRight(offsetL, offsetR)
            for color,rightString in argR:
                if colorDict.has_key(color):
                    # печатаем и считаем смещение
                    colorDict[color](rightString)
                else:
                    colorDict[''](rightString)
        if printBR:
            self._printSysOut.write("\n")
            try:
                self._printSysOut.flush()
            except IOError:
                cl_overriding.exit(1)

    def printNotOK(self, string, offsetL=0, printBR=True):
        """Вывод на печать в случае сбоя"""
        self._printSysOut = sys.stderr
        self.printLine((('greenBr',' * '),
                        ('',string),
                       ),
                       (('blueBr','['),
                        ('redBr',' !! '),
                        ('blueBr',']'),
                       ), offsetL, printBR)

    def printOnlyNotOK(self, string, offsetL=0, printBR=True):
        """Вывод на печать в случае сбоя"""
        self._printSysOut = sys.stderr
        self.printLine((('', string),),
                       (('blueBr','['),
                        ('redBr',' !! '),
                        ('blueBr',']'),
                       ), offsetL, printBR)

    def printOK(self, string, offsetL=0, printBR=True):
        """Вывод на печать в случае успеха"""
        self._printSysOut = sys.stdout
        self.printLine((('greenBr',' * '),
                        ('',string),
                       ),
                       (('blueBr','['),
                        ('greenBr',' ok '),
                        ('blueBr',']'),
                       ), offsetL, printBR)

    def printOnlyOK(self, string, offsetL=0, printBR=True):
        """Вывод на печать в случае успеха"""
        self._printSysOut = sys.stdout
        self.printLine((('',string),),
                       (('blueBr','['),
                        ('greenBr',' ok '),
                        ('blueBr',']'),
                       ), offsetL, printBR)

    def printWARNING(self, string, offsetL=0, printBR=True):
        """Вывод на печать предупреждения"""
        self._printSysOut = sys.stdout
        self.printLine((('yellowBr',' * '),
                        ('',string),
                       ),
                       (('',''),
                       ), offsetL, printBR)

    def printERROR(self, string, offsetL=0, printBR=True):
        """Вывод на печать ошибки"""
        self._printSysOut = sys.stderr
        self.printLine((('redBr',' * '),
                        ('',string),
                       ),
                       (('',''),
                       ), offsetL, printBR)

    def printSUCCESS(self, string, offsetL=0, printBR=True):
        """Вывод на печать в случае успеха без  [ok] справа"""
        self._printSysOut = sys.stdout
        self.printLine((('greenBr',' * '),
                        ('',string),
                       ),
                       (('',''),
                       ), offsetL, printBR)
