/***************************************************************************
 *   Copyright (C) 2007 by Daniel Prynych   *
 *   Daniel.Prynych@buzuluk.cz   *
 *                                                                         *
 *   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 "knutanalog.h"

/* pocitani uhlu */
/* nula je ve 3 hodiny */
/* prirustek je kladny ve smeru hod rucicek */

#include <stdio.h>
#include <math.h>

#include <tqpainter.h>
#include <tqframe.h>
#include <tqfontmetrics.h>
#include <tqfont.h>
#include <tqbitmap.h>
#include <tqpaintdevice.h>
#include <tqcolor.h>

#include <kapp.h>



KNutAnalog::KNutAnalog( TQWidget *parent, const char *name, int bottomLimit, int topLimit, int typeOfView, int countOfParts, int countOfSubParts, TQColor pointerColor, TQColor scaleColor, TQColor textColor, TQFont *analogFonts, int qualityOfPointer, bool makeBG )
    : TQFrame( parent, name ), m_bottomLimit(bottomLimit), m_topLimit(topLimit), m_typeOfView(typeOfView), m_countOfParts(countOfParts), m_countOfSubParts(countOfSubParts), m_pointerColor(pointerColor), m_scaleColor(scaleColor) ,m_textColor(textColor) {


  if ( qualityOfPointer==0) {
    m_speedOfAAlias=none;
    m_makeBlurMotion=false;
    }
  else {
    if ((qualityOfPointer==2) || (qualityOfPointer== 4)) m_speedOfAAlias=slow; else m_speedOfAAlias=fast;
    if ((qualityOfPointer==3) || (qualityOfPointer== 4)) m_makeBlurMotion=true; else m_makeBlurMotion=false;
    }

//  m_showBackGround = true;
//  m_showPointer = true;

  if (m_countOfParts > 6) m_countOfParts=6;
  else if (m_countOfParts < 2) m_countOfParts=2;


  if ( m_countOfSubParts > 6 ) m_countOfSubParts = 6;
  if ( m_countOfSubParts == 0 ) {
    if (m_countOfParts < 4) m_countOfSubParts =5;
    else {
      if (m_countOfParts < 6) m_countOfSubParts=4;
      else  m_countOfSubParts =3;
      }
    }

  m_valueOfPointer=m_bottomLimit;
  /* hodnoty zavisle na typu zobrazeni */
  switch (m_typeOfView) {
  case 1 :
    m_direction = 1; /* smer =1 ve smeru (clockwise), smer =-1 proti smeru hod. rucicek */
    m_angleOfViewer=270;
    m_startAngle=225;
    m_centerX=m_widthOfBackGround/2;
    m_centerY=m_widthOfBackGround/2;
    m_widthOfScale=118;
    m_radiusOfScaleNumbers=37;
    break;
  case 2 :
    m_direction = -1; /* smer =1 ve smeru (clockwise), smer =-1 proti smeru hod. rucicek */
    m_angleOfViewer=90;
    m_startAngle=0;
    m_centerX=13;
    m_centerY=110; 
    m_widthOfScale=210;
    m_radiusOfScaleNumbers=83;
    break;
  case 3 :
    m_direction = 1; /* smer =1 ve smeru (clockwise), smer =-1 proti smeru hod. rucicek */
    m_angleOfViewer=90;
    m_startAngle=135;
    m_centerX=m_widthOfBackGround/2;
    m_centerY=m_widthOfBackGround-15; 
    m_widthOfScale=170;
    m_radiusOfScaleNumbers=65;
    break;
  }
  // konec hodnot zavislych na typu zobrazeni

  if (analogFonts == 0) { // pokud neni predan font nastavi se systemovy font
    m_scaleFont = kapp->font();
    m_textFont = kapp->font();
  }
  else {
    m_scaleFont= *analogFonts;
    m_textFont= *analogFonts;
  }

  m_countOfColorParts = 0;
  setMinimumSize( AnalogWidth, AnalogWidth );
  setMaximumSize( AnalogWidth, AnalogWidth );
  setFrameStyle( TQFrame::Box | TQFrame::Raised );
  setLineWidth( 2 );

  m_backgroudLayerBig = new TQPixmap( (AnalogWidth-8) * 3,(AnalogWidth-8)*3 );

  m_scaleLayerBig = new TQPixmap ( (AnalogWidth-8)*3, (AnalogWidth-8)*3 ); //
  m_scaleLayerSmall = new TQPixmap ( (AnalogWidth-8), (AnalogWidth-8)); //

  m_wholeLayer = new TQPixmap ( AnalogWidth-8, AnalogWidth-8 ); //

  m_pointerLayerBig = new TQPixmap ( (AnalogWidth-8)*3, (AnalogWidth-8)*3 ); //
  m_pointerLayerSmall = new TQPixmap ( (AnalogWidth-8), (AnalogWidth-8)); //

  setDefaultArcColor(false); // sets standard registers // nastavime standartni registry

  if (makeBG) {
    paintBackGround();
    m_showBackGround = true;
    m_showPointer = true;
    }
  }

KNutAnalog::~KNutAnalog() {

  delete (m_backgroudLayerBig);

  delete (m_scaleLayerBig);
  delete (m_scaleLayerSmall);

  delete (m_pointerLayerBig);
  delete (m_pointerLayerSmall);

  delete (m_wholeLayer);
}


void KNutAnalog::makeBackground (bool run) {

  paintBackGround();
  m_showBackGround = true;
  if (run) {
    repaint();
    }
  }


void KNutAnalog::setText (TQString inscription, TQString text_up, bool run) {

  m_inscription=inscription;
  AnMJ=text_up;
  if (run) {
    paintBackGround();
    m_showBackGround = true;
    repaint();
    }
  }

void KNutAnalog::setDefaultArcColor(bool run) {

   m_arcColors[0] = TQt::white;
   m_arcColors[1] = TQt::green;
   m_arcColors[2] = TQt::yellow;
   m_arcColors[3] = TQt::red;
   m_arcColors[4] = TQt::blue;
   m_arcColors[5] = TQt::cyan;
   m_arcColors[6] = TQt::magenta;
   m_arcColors[7] = TQt::gray;
   m_arcColors[8] = TQt::black;
  if (run) {
    paintBackGround();
    m_showBackGround=true;
    repaint();
    }
  }


void KNutAnalog::setArcColor(int reg, TQColor color ) {
  if ((reg > -1) && (reg < 9)) m_arcColors[reg] = color;
  }


void KNutAnalog::addArc (double startOfCircle, double endOfCircle, int regColor, bool run) {

  if (m_countOfColorParts < 5) {
    m_extentOfDye[m_countOfColorParts].start=startOfCircle;
    m_extentOfDye[m_countOfColorParts].end=endOfCircle;
    if ((regColor <0) || (regColor > 8)) regColor=0;
    m_extentOfDye[m_countOfColorParts++].color=regColor;
    }
  if (run) {
    paintBackGround();
    m_showBackGround = true;
    repaint ();
    }
  }


void KNutAnalog::delArc (bool run) {

  m_countOfColorParts = 0;
  if (run) {
    paintBackGround();
    m_showBackGround = true;
    repaint ();
    }
  }



void KNutAnalog::setRange (int Astart, int Aend , bool run) {

  m_bottomLimit=Astart;
  m_topLimit=Aend;
  // pokud zmenime rozasah musime prekrelit i rucicku
  m_showPointer = true;
  if (run) {
     paintBackGround();
     m_showBackGround = true;
     repaint ();
     }
  }



void KNutAnalog::setMember (int Count, bool run) {

  m_countOfParts=Count;
  if (run) {
    paintBackGround();
    m_showBackGround = true;
    repaint ();
    }
  }



void KNutAnalog::setPointerColor (TQColor pointerColor,  bool run ) {

  m_pointerColor = pointerColor;
  paintPointer();
  m_showPointer = true;
  if (run) {
     repaint ();
    }
  }


void KNutAnalog::repaintPointer ( bool run ) {

  paintPointer();
  m_showPointer = true;
  if (run) {
     repaint ();
    }
  }


void KNutAnalog::setFontColor (TQColor fontColor,  bool run ) {

  m_textColor = fontColor;
//  paintBackGround();
//  m_showBackGround = true;
  if (run) {
     paintBackGround();
  m_showBackGround = true;
     repaint ();
    }
  }


void KNutAnalog::setScaleColor (TQColor scaleColor,  bool run) {

  m_scaleColor = scaleColor;
  if (run) {
    paintBackGround();
    m_showBackGround = true;
    repaint ();
    }
  }


void KNutAnalog::setDigitalProcesing (int qualityOfPointer, bool run ) {

  if (qualityOfPointer < 0) qualityOfPointer = 0;
  if (qualityOfPointer > 4) qualityOfPointer = 4;
  if ( qualityOfPointer==0) {
    m_speedOfAAlias=none;
    m_makeBlurMotion=false;
    }
  else {
    if ((qualityOfPointer==2) || (qualityOfPointer== 4)) m_speedOfAAlias=slow; else m_speedOfAAlias=fast;
    if ((qualityOfPointer==3) || (qualityOfPointer== 4)) m_makeBlurMotion=true; else m_makeBlurMotion=false;
    }
  paintPointer();
  m_showPointer = true; // pri jakemkoliv prekresleni prekreslime rucicku
  if (run) repaint ();
}



void KNutAnalog::setPointer (double pointerValue, bool run ) {
  if (m_valueOfPointer != pointerValue) {
    m_valueOfPointer = pointerValue;
    paintPointer();
    m_showPointer = true; // pri jakemkoliv prekresleni prekreslime rucicku
    if (run) {
//      paintPointer();
      m_showPointer = true; // pri jakemkoliv prekresleni prekreslime rucicku
      repaint ();
    }
  }
}



//************** PUBLIC SLOTS  **********************************

void KNutAnalog::slotSetScaleFont(TQFont newScaleFont){
  m_scaleFont = newScaleFont;
  paintBackGround();
  m_showBackGround=true;
  repaint();
  }

void KNutAnalog::slotSetTextFont(TQFont newTextFont){
  m_textFont = newTextFont;
  paintBackGround();
  paintPointer(); // repaint values if pointer
  m_showBackGround=true;
  m_showPointer=true;
  repaint();
  }

void KNutAnalog::slotSetAllFont(TQFont newAllFont){
  m_scaleFont = newAllFont;
  m_textFont = newAllFont;
  paintBackGround();
  paintPointer(); // repaint values if pointer
  m_showBackGround=true;
  m_showPointer=true;
  repaint();
  }


void KNutAnalog::repaintAll (void) {
  paintBackGround();
  m_showBackGround = true;
  m_showPointer = true;
  repaint ();
  }


//************** protected ****************************

void KNutAnalog::resizeEvent( TQResizeEvent * ) {
}


void KNutAnalog::paintEvent( TQPaintEvent *e ) {

  if (isVisible()) {
    TQFrame::paintEvent(e);
    if ((m_showBackGround) || (m_showPointer)) { // novou kompletni vrstvu sestavime jen pokud doslo ke zmene
      bitBlt( m_wholeLayer, 0, 0, m_scaleLayerSmall, 0, 0, m_widthOfBackGround, m_widthOfBackGround, CopyROP); //nakopirujeme vrstvu
      bitBlt( m_wholeLayer, 0, 0, m_pointerLayerSmall, 0, 0, m_widthOfBackGround, m_widthOfBackGround, AndROP ); //nakopirujeme rucicku
     }
    bitBlt( this , m_startOfBackGround, m_startOfBackGround, m_wholeLayer, 0, 0, m_widthOfBackGround, m_widthOfBackGround, CopyROP); //nakopirujeme vrstvu
    m_showBackGround = false;
    m_showPointer = false;
    }
  }


//***************private ************************

void KNutAnalog::paintBackGround ( void ) {
  TQPainter paint;
  TQImage myImage; //big image

//tqDebug ("KNutAnalog::paintBackGround");

  m_scaleLayerBig->fill( this,0,0); //color if background

  paint.begin ( m_scaleLayerBig );
  paint.setBackgroundMode(Qt::OpaqueMode);
  paint.setBackgroundColor(backgroundColor());
  paintPartOfCircle(&paint, m_centerX*3, m_centerY*3,m_widthOfScale*3);  //CMK pro inter
  paintScale(&paint, m_centerX*3, m_centerY*3,m_widthOfScale*3);  // Scale
  paint.end();

  myImage = m_scaleLayerBig->convertToImage();

  makeMotionBlur(&myImage,myImage.pixel(1,1),m_typeOfView);
  makeAntialiasing(&myImage,m_scaleLayerSmall,myImage.pixel(1,1),slow,m_typeOfView);

  paint.begin( m_scaleLayerSmall ); // paint on layer of scale
      // painting numbers
  paintScaleNumbers( &paint ); //painting of numbers
      // painting texts
  paintText( &paint );
  paint.end ();
  }



void KNutAnalog::paintPointer ( void ) {


//tqDebug ("KNutAnalog::paintPointer");
   if (m_speedOfAAlias == none)  paintPointerFastly (m_valueOfPointer);
   else paintPointerSlowly ( m_valueOfPointer, m_centerX*3, m_centerY*3,m_widthOfScale*3);
}


void KNutAnalog::paintPointerSlowly ( double position, int centerX , int centerY, int widthOfCircle) {
  TQPainter paint;

  TQImage myImage; //big image
  double angle;
  int lengthOfPointer = widthOfCircle / 2 - 12;

  if (position < m_bottomLimit) position=m_bottomLimit;
  else {
    if (position > m_topLimit) position = m_topLimit;
    }
  // painting of pointer
  angle = ((m_angleOfViewer/(m_topLimit-m_bottomLimit))*(position-m_bottomLimit))*((-1)*m_direction)+m_startAngle;

  m_pointerLayerBig->fill( TQt::white );  //color if beckground
  paint.begin( m_pointerLayerBig ); // paints of pointer
  paint.setBackgroundMode(Qt::TransparentMode);

  paint.setBrush( m_pointerColor ); // sets color
  paint.setPen ( m_pointerColor );
  TQPointArray pts;
  // k posuvu a k otoceni pouziva funkce paintu
  // for rotate and translate uses functions of paint
  paint.translate (centerX, centerY);
  paint.rotate(-angle);
  pts.setPoints( 4, -6, 0, 0, -6, lengthOfPointer, 0, 0, 6 );
  paint.drawConvexPolygon( pts );

  paint.end ();
  //m_pointerMutex.lock();

  myImage = m_pointerLayerBig->convertToImage();

  if (m_makeBlurMotion) makeMotionBlur(&myImage,myImage.pixel(1,1));
  makeAntialiasing(&myImage,m_pointerLayerSmall,myImage.pixel(1,1),m_speedOfAAlias,0);

  paint.begin( m_pointerLayerSmall ); // paints on layer's background
  paintValueOfPointer ( &paint, m_valueOfPointer);
  paint.end ();
 // m_pointerMutex.unlock();
  }



void KNutAnalog::paintPointerFastly (double position) {
  TQPainter paint;
  double uhel;

  int delka = m_widthOfScale / 2 - 4;

  //m_pointerMutex.lock();
  m_pointerLayerSmall->fill( TQt::white );  //background color
  paint.begin( m_pointerLayerSmall ); // kreslime na plochu rucicky
  paint.setBackgroundMode(Qt::TransparentMode);
  paintValueOfPointer ( &paint, m_valueOfPointer);


  if (position < m_bottomLimit) position=m_bottomLimit;
  else {
    if (position > m_topLimit) position = m_topLimit;
    }
  /* painting of pointer*/
  uhel = ((m_angleOfViewer/(m_topLimit-m_bottomLimit))*(position-m_bottomLimit))*((-1)*m_direction)+m_startAngle;

  paint.setBrush( m_pointerColor ); // nastavime barvu
  paint.setPen ( m_pointerColor );
  TQPointArray pts;
  // for translate a rotate uses functions of paint // k posuvu a k otoceni pouziva funkce paintu
  paint.translate (m_centerX, m_centerY);
  paint.rotate(-uhel);
  pts.setPoints( 4, -2, 0, 0, -2, delka, 0, 0, 2 );
  paint.drawPolygon( pts );

  paint.end();
  //m_pointerMutex.unlock();
  }



void KNutAnalog::paintPartOfCircle ( TQPainter *paint, int centerX , int centerY, int widthOfCircle ) {
  double Astart, Aend;

  // pocitani uhlu
  //nula je ve 3 hodiny
  // prirustek je kladny proti smeru hod rucicek

  //int extent = m_topLimit-m_bottomLimit; //rozsah
//  double extent = m_topLimit-m_bottomLimit; //rozsah
//  double jednotka = ((double)m_angleOfViewer/extent);
  double jednotka = ((double)m_angleOfViewer/(m_topLimit-m_bottomLimit));
  bool painted = false;

//  int smerMK = (-1)*m_direction;
  // paints parts of circle
  for (int i=0;i<m_countOfColorParts;i++) {
    if ((m_extentOfDye[i].start < m_topLimit) && (m_extentOfDye[i].end > m_bottomLimit)) {
      if (m_extentOfDye[i].start < m_bottomLimit) Astart = m_bottomLimit; else Astart = m_extentOfDye[i].start;
      if (m_extentOfDye[i].end > m_topLimit) Aend = m_topLimit; else Aend = m_extentOfDye[i].end;
      paint->setBrush ( m_arcColors[m_extentOfDye[i].color] );
      paint->setPen (NoPen);
      paint->drawPie((centerX-widthOfCircle/2),(centerY-widthOfCircle/2),widthOfCircle,widthOfCircle,(int)((((Astart-m_bottomLimit)*jednotka)*((-1)*m_direction)+m_startAngle)*16),(int)(((-1)*m_direction)*((Aend-Astart)*jednotka)*16));
      painted = true; // bylo provedeno vykresleni
      }
    }
  if ((m_countOfColorParts > 0) && (painted)) { // kreslime jen pokud bylo kreslena kruhova vysec
    // musime vybarvit stred kotouce
    //fills center of circle
    paint->setBrush ( paint->backgroundColor() ); //The angles  are 1/16th of a degree
    paint->drawPie((centerX-(widthOfCircle/2)+18),(centerY-(widthOfCircle/2)+18),widthOfCircle-36,widthOfCircle-36,(int)(m_startAngle*16+90*m_direction),(int)((-m_direction)*(m_angleOfViewer*16+180)));
    }
  }



void KNutAnalog::paintScale ( TQPainter *paint , int centerX , int centerY, int widthOfCircle) {

  int bottomMax = widthOfCircle/2 - 29;
  int bottom = widthOfCircle/2 -17 ;
  int smer_stup = (-1)*m_direction;
  paint->save();
  paint->setPen ( m_scaleColor);

  paint->translate( centerX, centerY );

  double stupne = smer_stup * (m_angleOfViewer/(m_countOfParts*(m_countOfSubParts)));

  // nakresleni prvni linky
  //paints of the first line
  paint->rotate( -m_startAngle);
  paint->setBrush ( m_scaleColor );
  paint->drawRect( bottomMax,-1,30,3 );

  for ( int i=0; i<(m_countOfParts); i++ ) {
    for ( int j=0; j<(m_countOfSubParts-1); j++) {
      paint->rotate( -stupne );
      paint->drawRect( bottom,-1,18,2 );
      }
    paint->rotate( -stupne );
    paint->drawRect( bottomMax,-1,30,3 );
    }
  paint->restore();
  }



void KNutAnalog::makeAntialiasing (TQImage* bigImage, TQPixmap* smallPixmap, const TQRgb colorOfBG, speedOfAAlias speed, int typeOfView) {
  ulong imageRed, imageGreen, imageBlue;
  TQRgb imageRgb;
  TQImage* smallImage;
  bool computeAverage;
  ulong sumOfRed, sumOfGreen, sumOfBlue;

  if (speed == slow) {
    sumOfRed =  (tqRed ( colorOfBG ))*9;
    sumOfGreen = (tqGreen ( colorOfBG ))*9;
    sumOfBlue = (tqBlue ( colorOfBG ))*9;
    }
  else {
    sumOfRed =  (tqRed ( colorOfBG ))*16;
    sumOfGreen = (tqGreen ( colorOfBG ))*16;
    sumOfBlue = (tqBlue ( colorOfBG ))*16;
    }
  int smallImageWidth=bigImage->width()/3;
  int smallImageHeight=bigImage->height()/3;


  smallImage = new TQImage(smallImageWidth,smallImageHeight, bigImage->depth());

//  imageRgb = bigImage->pixel(1,1);

  for (int x = 0; x < smallImageWidth; x++) {
    for (int y = 0; y < smallImageHeight; y++) {
      imageRed = 0;
      imageGreen = 0;
      imageBlue = 0;

      switch (typeOfView) {
        case 0: 
        //nothing
        computeAverage=true;
        break;
        case 1:
        if ((y>25) and (x >30) and (x < 92)) computeAverage=false;
        else computeAverage=true;
        break;
        case 2:
        if ((y < 15) || ((x+15) > y)) computeAverage=true;
        else computeAverage=false;
        break;
        case 3:
        //computes top part only
        if ((y < 60) && (y>15)) computeAverage=true;
        else computeAverage=false;
        break;
        default:
        computeAverage=true;
        }

      if (speed == slow) {
////  uses divide, slowly compute
        if (computeAverage) {
          for (int xi = 0 ; xi < 3; xi ++) {
            for (int yi = 0 ; yi < 3; yi ++) {
            imageRgb = bigImage->pixel(x*3+xi,y*3+yi);
            imageRed +=  tqRed ( imageRgb );
            imageGreen += tqGreen ( imageRgb );
            imageBlue += tqBlue ( imageRgb );
            }
          }
          if (((imageRed == sumOfRed) && (imageGreen == sumOfGreen) && (imageBlue == sumOfBlue))) {
            smallImage->setPixel (x,y,colorOfBG);
             }
          else {
            imageRed = imageRed / 9;
            imageGreen = imageGreen/9;
            imageBlue = imageBlue/9;
            smallImage->setPixel (x,y,tqRgb(imageRed,imageGreen,imageBlue));
            }
          }
        else {
          smallImage->setPixel (x,y,bigImage->pixel(x*3,y*3));
          }
        }
      else {
////  uses bitmove, fastly compute
        if (computeAverage) {
          for (int xi = 0 ; xi < 3; xi ++) {
            for (int yi = 0 ; yi < 3; yi ++) {
              if ((xi == 1) && (yi == 1)) { // center of 3x3 area
                imageRgb = bigImage->pixel(x*3+xi,y*3+yi);
                imageRed +=  tqRed ( imageRgb )*4;
                imageGreen += tqGreen ( imageRgb )*4;
                imageBlue += tqBlue ( imageRgb )*4;
                }
              else {
                if ((xi == 1) || (yi == 1))    {
                  imageRgb = bigImage->pixel(x*3+xi,y*3+yi);
                  imageRed +=  tqRed ( imageRgb )*2;
                  imageGreen += tqGreen ( imageRgb )*2;
                  imageBlue += tqBlue ( imageRgb )*2;
                  }
                else {
                  imageRgb = bigImage->pixel(x*3+xi,y*3+yi);
                  imageRed +=  tqRed ( imageRgb );
                  imageGreen += tqGreen ( imageRgb );
                  imageBlue += tqBlue ( imageRgb );
                  }
                }
              }
            }
          if ((imageRed == sumOfRed) && (imageGreen == sumOfGreen) && (imageBlue == sumOfBlue)) {
             smallImage->setPixel (x,y,colorOfBG);
             }
          else {
            imageRed = imageRed >> 4;
            imageGreen = imageGreen >> 4;
            imageBlue = imageBlue >> 4;
            smallImage->setPixel (x,y,tqRgb(imageRed,imageGreen,imageBlue));
            }
          }
        else {
          smallImage->setPixel (x,y,bigImage->pixel(x*3,y*3));
          }
        } //end of fastly
      }
    }
  smallPixmap->convertFromImage(*smallImage);
  delete smallImage;
}


void KNutAnalog::makeMotionBlur (TQImage* image, const TQRgb colorOfBG, int typeOfView) {

  ulong imageRed, imageGreen, imageBlue;
  TQRgb imageRgb;
  TQImage *layerImageBlur;
  bool computeAverage;
  int startHeight, stopHeight;
  ulong sumOfRed, sumOfGreen, sumOfBlue;

  sumOfRed =  (tqRed ( colorOfBG ))*9;
  sumOfGreen = (tqGreen ( colorOfBG ))*9;
  sumOfBlue = (tqBlue ( colorOfBG ))*9;

  int imageWidth=image->width();
  int imageHeight=image->height();

  layerImageBlur = new TQImage(*image);
  layerImageBlur->detach(); //costructor makes swallow copy, have to use detach


   switch (typeOfView) {
     case 0: 
     //nothing
     startHeight =1;
     stopHeight =imageHeight-2;
     break;
     case 2:
     startHeight =1;
     stopHeight =imageHeight-2;
     break;
     case 3: 
     startHeight =45;
     stopHeight =180;
     break;
     default:
     startHeight =1;
     stopHeight =imageHeight-2;
     }


  for (int x = 1; x < imageWidth-2; x++) {
    for (int y = startHeight; y < stopHeight; y++) {
      imageRed = 0;
      imageGreen = 0;
      imageBlue = 0;

      switch (typeOfView) {
        case 0: 
        //nothing
        computeAverage=true;
        break;
        case 1:
        if ((y>75) and (x >90) and (x < 274)) computeAverage=false;
        else computeAverage=true;
        break;
        case 2:
        if ((y < 45) || ((x+45) > y)) computeAverage=true;
        else computeAverage=false;
        break;
        case 3:
        //computes top part only
        if ((y < 180) && (y>45)) computeAverage=true;
        else computeAverage=false;
        break;
        default:
        computeAverage=true;
        }


      if (computeAverage) {
        for (int xi = -1 ; xi < 2; xi ++) {
          for (int yi = -1 ; yi < 2; yi ++) {
            imageRgb = layerImageBlur->pixel(x+xi,y+yi);
            imageRed +=  tqRed ( imageRgb );
            imageGreen += tqGreen ( imageRgb );
            imageBlue += tqBlue ( imageRgb );
            }
          }

        if (!((imageRed == sumOfRed) && (imageGreen == sumOfGreen) && (imageBlue == sumOfBlue))) {
          imageRed = (int)(imageRed / 9);
          imageGreen = (int)(imageGreen/9);
          imageBlue = (int)(imageBlue/9);
          image->setPixel (x,y,tqRgb(imageRed,imageGreen,imageBlue));
          }
        }
      }
    }
  delete layerImageBlur;
}






void KNutAnalog::paintScaleNumbers ( TQPainter *paint ) {
  //paintig of scaleNumbers

  int poz_x, poz_y, r_vyska, r_sirka;
  double posun, angle;

  double upi = 0.0174532;
  int smer_st = -m_direction;

  paint->save();  // ulozime
  TQString cislo;
  paint->setPen(m_textColor);
  paint->setFont(m_scaleFont);

  TQFontMetrics fm = paint->fontMetrics();
  r_vyska = ((fm.ascent()) / 2);
  posun = ((double)(m_topLimit-m_bottomLimit))/m_countOfParts;
  for (int i=0; i<=(m_countOfParts);i++) {
    cislo.sprintf( "%3.0f",m_bottomLimit+i*posun);
    cislo=cislo.stripWhiteSpace();
    r_sirka = (fm.width(cislo))/2;
    angle = (m_startAngle+ ((m_angleOfViewer/m_countOfParts)*i*smer_st))*upi;
    poz_x = (int)((cos(angle)*m_radiusOfScaleNumbers+m_centerX) - r_sirka);
    poz_y = (int)((m_centerY-sin(angle)*m_radiusOfScaleNumbers) + r_vyska);
    paint->drawText (poz_x,poz_y,cislo);
    }
  paint->restore();
  }


void KNutAnalog::paintText ( TQPainter *paint ) {
  TQString nadpis1;
  TQString nadpis2;
  int index;

  if (m_inscription.length() >1) {
    if ((index = m_inscription.find(" ")) != -1) {
    // mezera nalezena space found
      nadpis1 = m_inscription.left(index);
      nadpis2 = m_inscription.mid(index+1,(uint)(m_inscription.length() - index - 1));
      }
    } else index = -1;

  paint->setPen(m_textColor);
  paint->setFont(m_textFont);
  TQFontMetrics fm = paint->fontMetrics();
  int r_vyska = fm.height()/ 2;
  switch (m_typeOfView)	{
    // kruznice - kreslime dve radky nad sebou cemtrovane
    case 1 :
      if (index == -1 ) paint->drawText( m_centerX - fm.width(m_inscription)/2, 104 + r_vyska , m_inscription);
      else {
        // mame dve slova
        paint->drawText( m_centerX - fm.width(nadpis1)/2, 106 + r_vyska/2 - 2, nadpis1);
        paint->drawText( m_centerX - fm.width(nadpis2)/2, 106 + (r_vyska*3)/2 + 2, nadpis2);
        }
      paint->drawText( m_centerX - fm.width(AnMJ)/2, 44 + r_vyska , AnMJ);
      break;
      // ctvrt oblouk kreslime dve radky nad sebou centrovane v pravem hornim rohu
    case 2 :
      if (index == -1 ) paint->drawText( 121 - fm.width(m_inscription) , 6 + r_vyska , m_inscription);
      else {
        paint->drawText( 121 - fm.width(nadpis1) , 6 + r_vyska , nadpis1);
        paint->drawText( 121 - fm.width(nadpis2) , 10 + r_vyska*2 , nadpis2);
        }
      paint->drawText( m_centerX , 68 + r_vyska*2 , AnMJ);
      break;
    // horni oblouk
    case 3 :
      paint->drawText( m_centerX - fm.width(m_inscription)/2, 6 + r_vyska , m_inscription);
      paint->drawText( m_widthOfBackGround -5 -fm.width(AnMJ), m_widthOfBackGround -r_vyska, AnMJ);

      break;
    }
  }



void KNutAnalog::paintValueOfPointer ( TQPainter *p, double value) {

  TQString cislo;
  cislo.sprintf( "%5.1f",value);
  cislo=cislo.stripWhiteSpace();

  if (value < m_bottomLimit) value=m_bottomLimit;
  else {
    if (value > m_topLimit) value = m_topLimit;
    }
  /* nakresleni rucicky*/
//  uhel = ((uhel_zobrazeni/(horni_mez-dolni_mez))*(value-dolni_mez))*((-1)*smer)+m_startAngle;

  p->setPen(m_textColor);
  p->setFont(m_textFont);
  TQFontMetrics fm = p->fontMetrics();
  int r_vyska = fm.height()/ 2;


  switch (m_typeOfView) {
    case 1 :
      p->drawText( m_centerX - fm.width(cislo)/2, 75 + r_vyska , cislo);
    break;
    case 2 :
      p->drawText( m_centerX , 57 + r_vyska , cislo);
    break;
    case 3 :
      p->drawText( 5, m_widthOfBackGround -r_vyska, cislo);
    break;
    }
  }



#include "knutanalog.moc"