/***************************************************************************
                          knutpanelmeter.cpp  -  description
                             -------------------
    begin                : Út b?e 16 2004
    copyright            : (C) 2004 by Daniel Prynych
    email                : Daniel.Prynych@alo.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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "knutpanelmeter.h"

#include <qlayout.h>
#include <qlabel.h>
#include <qfont.h>


#include <math.h>
#include <stdlib.h>
#include <unistd.h>


extern const char *nameUpsVars1[];
extern const char *nameUpsVars2[];


KNutPanelMeter::KNutPanelMeter(QPalette taPanelPalette, struct upsInfo* tActiveUpsInfo, SettingDataDef* tSettingData, KNutVarData* tAnalogRecords, QWidget *parent, const char *name ) : QScrollView(parent,name,Qt::WResizeNoErase|Qt::WStaticContents) {

  settingData = tSettingData;
  activeUpsInfo = tActiveUpsInfo;
  analogRecords = tAnalogRecords;
  aPanelPalette = taPanelPalette;

  analogArea = new QLabel(this->viewport());
  addChild(analogArea);
  setResizePolicy ( QScrollView::AutoOneFit ) ;
  

////NUTNO PAK UPRAVIT ACTIVATE A DEAKTIVATE ANALOGS
 analogPanels = new analogPanelsRecord;
    for (int i=0; i< knc::NumberOfVars; i++)
      analogPanels->upsAnalogs[i]=0L;

  widthArea =0;
  heightArea =0;
 }

KNutPanelMeter::~KNutPanelMeter(){

  deActivateAnalogs();
  delete analogPanels;
  analogPanels=0L;
  }



void KNutPanelMeter::deActivateAnalogs (void) {

  if (analogPanels) {
    for (int i=0; i< knc::NumberOfVars; i++) {
      if (analogPanels->upsAnalogs[i] != 0) {
        delete analogPanels->upsAnalogs[i]; // uvolnime meraky
        }
      analogPanels->upsAnalogs[i]=0L;
      }
    }
  widthArea =0;
  heightArea =0;
  }

void KNutPanelMeter::activateAnalogs (void) {
  VarStrucDef analogMemberData;
  int ii =0;
  // vyjmeme promene ktere ups nepodporuje

  //// nasledujici radka neni nutna
  for (int i=0; i< knc::NumberOfVars; i++) analogPanels->upsAnalogs[i]=0L;
  for (int i=0; i< knc::NumberOfVars; i++) {
    // otestujeme zda dane UPS podporuje tuto promenou
    // pokud existuje vrati 1
    switch (activeUpsInfo->nutVariables) {
      case 1:
        if (!activeUpsInfo->upsNet->existName(nameUpsVars1[activeUpsInfo->record.upsVarCode[i]]))
          activeUpsInfo->record.upsVarCode[ii++] = activeUpsInfo->record.upsVarCode[i];
      break;
      case 2:
        if (!activeUpsInfo->upsNet->existName(nameUpsVars2[activeUpsInfo->record.upsVarCode[i]]))
          activeUpsInfo->record.upsVarCode[ii++] = activeUpsInfo->record.upsVarCode[i];
      break;
      }
    }
  for (int i=ii; i< knc::NumberOfVars; i++) activeUpsInfo->record.upsVarCode[i]=0;// doplnime zbytek nulami to znamena zadna promena

  for (int i=0; i< knc::NumberOfVars; i++) {
    if (activeUpsInfo->record.upsVarCode[i] != 0) {
      analogRecords->getData (activeUpsInfo->record.upsVarCode[i], analogMemberData);
      analogPanels->scaleEnd[i]=analogMemberData.end;
      analogPanels->scaleStart[i]=analogMemberData.start;
      QColor analogFingerColor, analogScaleColor, analogFontColor;
      if (settingData->customOAnalogColor) {
        analogFingerColor = settingData->analogFingerColor;
        analogScaleColor = settingData->analogScaleColor;
        analogFontColor = settingData->analogFontColor;
        }
      else {
        analogFingerColor = DEFAULT_FINGER_COLOR;
        analogScaleColor = DEFAULT_SCALE_COLOR;
        analogFontColor = DEFAULT_FONT_COLOR;
        }

      if (settingData->customFont)
        analogPanels->upsAnalogs[i] = new KAnalog( analogArea,0L,analogMemberData.start,analogMemberData.end,analogMemberData.typeAnalog,analogMemberData.numberItem,analogMemberData.numberInItem,analogFingerColor,analogScaleColor,analogFontColor,&(settingData->aPanelFont));
      else
        analogPanels->upsAnalogs[i] = new KAnalog( analogArea,0L,analogMemberData.start,analogMemberData.end,analogMemberData.typeAnalog,analogMemberData.numberItem,analogMemberData.numberInItem,analogFingerColor,analogScaleColor,analogFontColor,&(settingData->systemFont));
      //nastavime barvu mezikruzi


      if (settingData->customOAnalogColor) {
        analogPanels->upsAnalogs[i]->setArcColor(1,settingData->analogOKColor);
        analogPanels->upsAnalogs[i]->setArcColor(2,settingData->analogWarnningColor);
        analogPanels->upsAnalogs[i]->setArcColor(3,settingData->analogErrorColor);
        }
      // po vygenerovani panelu jsou standartni barvy nastaveny automaticky
      //nastavime mezikruzi
      for (int j = 0; j < 5; j++ ) {
        if (!((analogMemberData.scaleData[j].start == 0) && (analogMemberData.scaleData[j].end ==0 ))) {
          analogPanels->upsAnalogs[i]->addArc (analogMemberData.scaleData[j].start,analogMemberData.scaleData[j].end,analogMemberData.scaleData[j].scaleColor, false);
        }
      }
      analogPanels->upsAnalogs[i]->setText(analogMemberData.nameAnalog,analogMemberData.nameUnit);
      analogPanels->upsAnalogs[i]->setPalette(aPanelPalette);
      }
    }
  analogArea->repaint();
///  analogSV->resizeContents(sizeHint().width(),sizeHint().height());

  }



void KNutPanelMeter::setSize (bool showPanels) {
    int row =0;
    int col=0;
    int maxCols =0;
    int maxRows =0;

    if (!activeUpsInfo->netError) {
      for (int i=0; i< knc::NumberOfVars; i++) {
        if (activeUpsInfo->record.upsVarCode[i] != 0) {
          if (maxCols < settingData->countCols) maxCols++;
          maxRows = row+1;
          // jestlize upsAnalogs =0 nejsou aktivovany
          if (analogPanels->upsAnalogs[i]) {
            analogPanels->upsAnalogs[i]->move (SpacePanels + (SpacePanels)+(col*(KAnalog::AnalogWidth+SpacePanels)),SpacePanels+(row*(KAnalog::AnalogWidth+SpacePanels)));
            if (showPanels) analogPanels->upsAnalogs[i]->show();
            }
          col++;
          if (col > (settingData->countCols-1) ) {col=0; row++;}; // prechod na dalsi radku
          }
        }
      }
    // musime nastavit velikost
    widthArea = (KAnalog::AnalogWidth + SpacePanels)*maxCols +2*SpacePanels; // sirka
    heightArea = (KAnalog::AnalogWidth + SpacePanels)*(maxRows) + SpacePanels; // minimalni velikost podle mericich panelu

    analogArea->setMinimumSize (widthArea,heightArea);
    adjustSize();
    resizeContents(widthArea,heightArea);
    repaint();
  }

void KNutPanelMeter::repaintScaleAnalogPanel (int panelNumber, float value) {

  if (analogPanels->upsAnalogs[panelNumber] != 0L){
    switch (activeUpsInfo->record.upsVarCode[panelNumber]) {
      case knc::VarCurrent : // output.current
        if (analogPanels->scaleEnd[panelNumber] < MaxCurrent) {
          if (analogPanels->scaleEnd[panelNumber] < value) {
            analogPanels->scaleEnd[panelNumber]=(static_cast<int>(floor((value+1)/5)))*5 +5;
            if (analogPanels->scaleEnd[panelNumber] > MaxCurrent) analogPanels->scaleEnd[panelNumber]=MaxCurrent;
              analogPanels->upsAnalogs[panelNumber]->setRange(analogPanels->scaleStart[panelNumber],analogPanels->scaleEnd[panelNumber],true);
            }
          }
        break;
      case knc::VarBattVolt : // battery.voltage
        if (analogPanels->scaleEnd[panelNumber] < MaxBattVolt) {
          if (analogPanels->scaleEnd[panelNumber] < value) {
            analogPanels->scaleEnd[panelNumber]=(static_cast<int>(floor((value+1)/10)))*10 +10;
            if (analogPanels->scaleEnd[panelNumber] > MaxBattVolt) analogPanels->scaleEnd[panelNumber]=MaxBattVolt;
              analogPanels->upsAnalogs[panelNumber]->setRange(analogPanels->scaleStart[panelNumber],analogPanels->scaleEnd[panelNumber],true);
            }
          }
        break;
      case knc::VarBattCurrent : // battery.current
        if (analogPanels->scaleEnd[panelNumber] < MaxBattCurrent) {
          if ((analogPanels->scaleEnd[panelNumber] < value) || (analogPanels->scaleStart[panelNumber] > value)) {
            if ((value >10) || (value <- 15)) {
              if ((value >20) || (value < -30)) {
                analogPanels->scaleEnd[panelNumber]=30;
                analogPanels->scaleStart[panelNumber]=-45;
                 }
              else {
                analogPanels->scaleEnd[panelNumber]=20;
                analogPanels->scaleStart[panelNumber]=-30;
                }
              analogPanels->upsAnalogs[panelNumber]->setFinger(value); // jistota pokud by nam to nekde propadlo
              analogPanels->upsAnalogs[panelNumber]->hide();// schovame analogovy panel   hides analog panel
              analogPanels->upsAnalogs[panelNumber]->setRange (analogPanels->scaleStart[panelNumber],analogPanels->scaleEnd[panelNumber]);
              analogPanels->upsAnalogs[panelNumber]->repaint(); // prekreslime , repaints panel
              analogPanels->upsAnalogs[panelNumber]->show(); //zobrazime merak  shows analog panel
              }
            }
         }
       break;
      } // end switch
    }
  }

void KNutPanelMeter::repaintAnalogFinger (int panelNumber, float value) {
  if (analogPanels->upsAnalogs[panelNumber] != 0L)
     analogPanels->upsAnalogs[panelNumber]->setFinger (value); // nastavi hodnotu rucicky
  }


void KNutPanelMeter::setAnalogBG(QPalette taPanelPalette) {

  aPanelPalette = taPanelPalette;
  for (int i=0; i< knc::NumberOfVars; i++) {
    if ((activeUpsInfo->record.upsVarCode[i]) && (analogPanels->upsAnalogs[i]))
      analogPanels->upsAnalogs[i]->setPalette(aPanelPalette);
    }
 }

        
void KNutPanelMeter::repaintAnalogPanels (bool repaintFrequencyPanels, bool repaintVoltagePanels, bool repaintAllPanels) {
VarStrucDef analogMemberData;

  if (analogPanels == 0) return;

  // pregenerovani panelu slouzi pro settingMain a setting Analog
  for (int i=0; i< knc::NumberOfVars; i++) {
    if ((activeUpsInfo->record.upsVarCode[i]) && (analogPanels->upsAnalogs[i])) {
      if (((activeUpsInfo->record.upsVarCode[i] == knc::VarAcfreq) && (repaintFrequencyPanels)) ||
           (((activeUpsInfo->record.upsVarCode[i] == knc::VarUtility) ||
             (activeUpsInfo->record.upsVarCode[i] == knc::VarOutVolt)) && (repaintVoltagePanels))) {
        analogRecords->getData (activeUpsInfo->record.upsVarCode[i], analogMemberData); // nacteme data
        analogPanels->upsAnalogs[i]->hide();// schovame analogovy panel
        analogPanels->upsAnalogs[i]->delArc(); //zrusime segmenty
        analogPanels->upsAnalogs[i]->setRange (analogMemberData.start,analogMemberData.end);
        for (int j = 0; j < 5; j++ ) {
          if (!((analogMemberData.scaleData[j].start == 0) && (analogMemberData.scaleData[j].end ==0 ))) {
            analogPanels->upsAnalogs[i]->addArc (analogMemberData.scaleData[j].start,analogMemberData.scaleData[j].end,analogMemberData.scaleData[j].scaleColor, false);
            } // end if (!
          }// end for (int i=0
        analogPanels->upsAnalogs[i]->repaint(); // prekreslime
        analogPanels->upsAnalogs[i]->show(); //zobrazime merak
        } // end if (((activeUpsInfo
      if (repaintAllPanels) {
        if (settingData->customOAnalogColor) {
          analogPanels->upsAnalogs[i]->setFingerColor(settingData->analogFingerColor);
          analogPanels->upsAnalogs[i]->setArcColor(1,settingData->analogOKColor);
          analogPanels->upsAnalogs[i]->setArcColor(2,settingData->analogWarnningColor);
          analogPanels->upsAnalogs[i]->setArcColor(3,settingData->analogErrorColor);
          analogPanels->upsAnalogs[i]->setScaleColor(settingData->analogScaleColor);
          analogPanels->upsAnalogs[i]->setFontColor(settingData->analogFontColor);
          }
        else {
          analogPanels->upsAnalogs[i]->setFingerColor (DEFAULT_FINGER_COLOR);
          analogPanels->upsAnalogs[i]->setDefaultArcColor();
          analogPanels->upsAnalogs[i]->setScaleColor (DEFAULT_SCALE_COLOR);
          analogPanels->upsAnalogs[i]->setFontColor (DEFAULT_FONT_COLOR);
          }
        analogPanels->upsAnalogs[i]->repaintAll();
        }
      }
    } // end for
  }

void KNutPanelMeter::zeroingPanels (void) {
  if (analogPanels) {
    for (int i=0; i< knc::NumberOfVars; i++) {
      if ((analogPanels->upsAnalogs[i] != 0L) && (activeUpsInfo->record.upsVarCode[i] != 0)) // jistota pokud by nam to nekde propadlo
        analogPanels->upsAnalogs[i]->setFinger (0); // nastavi hodnotu rucicky
      }
    }
  }
    
QSize KNutPanelMeter::sizeHint (void){

  return QSize(widthArea,heightArea);
  }


void KNutPanelMeter::slotSetPanelsFont(QFont newFont) {

  for (int i=0; i< knc::NumberOfVars; i++) {
    if ((activeUpsInfo->record.upsVarCode[i]) && (analogPanels->upsAnalogs[i])) {
      analogPanels->upsAnalogs[i]->slotSetAllFont(newFont);
      }
    }
  }

#include "knutpanelmeter.moc"


syntax highlighted by Code2HTML, v. 0.9.1