/***************************************************************************
 *   Copyright (C) 2007 by Andreas Krumnow   *
 *   andreas@krumnow.de   *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#include "seitenspiegel.h"
#include <math.h>

seitenspiegel::seitenspiegel()
{
    docSize = 150;
    minBlockSize = 4;
    maxBlockSize = 10;
    quitButton = new QPushButton( tr("&Quit") );

    btn_calc = new QPushButton( tr("&berechnen"));

    lbl_docSize = new QLabel( this );
    lbl_docSize->setObjectName( QString::fromUtf8("lbl_docSize") );
    lbl_docSize->setScaledContents( true );
    lbl_docSize->setText( tr("&Seiten ges.  ") );
    lbl_Ergebnis = new QLabel( this );
    lbl_Ergebnis->setObjectName( QString::fromUtf8("lbl_Ergebnis") );
    lbl_Ergebnis->setText( QApplication::translate("Dialog", "Druckreihenfolge:", 0, QApplication::UnicodeUTF8) );

    spx_docSize = new QSpinBox( this);
    spx_docSize->setObjectName( QString::fromUtf8("spx_docSize"));
    spx_docSize->setMaximum( 4095 );
    spx_docSize->setMinimum( 4 );
    spx_docSize->setSingleStep( 1 );
    spx_docSize->setValue( docSize );
    spx_docSize->setToolTip( tr("&Seitenzahl des Dokuments") );
    lbl_docSize->setBuddy( spx_docSize );

    sld_BlockSize = new QSlider( this );
    sld_BlockSize->setObjectName( QString::fromUtf8("sld_BlockSize") );
    sld_BlockSize->setMinimum( 2 );
    sld_BlockSize->setMaximum( 26 );
    sld_BlockSize->setValue( minBlockSize );
    sld_BlockSize->setOrientation( Qt::Horizontal );
    sld_BlockSize->setTickPosition( QSlider::TicksBelow );
    sld_BlockSize->setTickInterval( 1 );

    rdb_min = new QRadioButton( this );
    rdb_min->setText( tr("mi&n.  4 Blatt / Block") );
    rdb_max = new QRadioButton( this );
    rdb_max->setText( tr("ma&x.  10 Blatt / Block") );
    rdb_min->setChecked( true );
    minmax_rdb = rdb_min;
    minmax = &minBlockSize;
    txt_rdb = "min. ";

    txt_ergebnis = new QTextBrowser( this );
    txt_ergebnis->setObjectName( QString::fromUtf8("txt_ergebnis") );
    txt_ergebnis->setCursor( QCursor(static_cast<Qt::CursorShape>(0)) );
    txt_ergebnis->setOverwriteMode( true );
    txt_ergebnis->setTabStopWidth( 8 );
    txt_ergebnis->setPlainText( "" );


    connect( quitButton, SIGNAL(clicked()), qApp, SLOT(quit()) );
    connect( spx_docSize, SIGNAL( valueChanged(int)), this, SLOT(on_spx_docSize( int )) );
    connect( sld_BlockSize, SIGNAL( valueChanged(int)), this, SLOT(on_sld_BlockSize(int)) );
    connect( btn_calc, SIGNAL( clicked()), this, SLOT(on_btn_calc()) );
    connect( rdb_min, SIGNAL(toggled(bool)), this, SLOT(on_rdb_min(bool)) );
    connect( rdb_max, SIGNAL(toggled(bool)), this, SLOT(on_rdb_max(bool)) );

    gridLayout = new QGridLayout;
    gridLayout->addWidget( lbl_docSize,   0, 0, 1, 1 );
    gridLayout->addWidget( rdb_min,       0, 1, 1, 2 );
    gridLayout->addWidget( rdb_max,       0, 3, 1, 2 );
    gridLayout->addWidget( spx_docSize,   1, 0, 1, 1 );
    gridLayout->addWidget( sld_BlockSize, 1, 1, 1, 4 );
    gridLayout->addWidget( lbl_Ergebnis,  2, 0, 1, 1 );
    gridLayout->addWidget( btn_calc,      2, 1, 1, 1 );
    gridLayout->addWidget( quitButton,    2, 4, 1, 1 );
    gridLayout->addWidget( txt_ergebnis,  3, 0, 1, 5 );
    setLayout( gridLayout );

    btn_calc->setAutoDefault ( true );
    btn_calc->setDefault ( true );
    resize( 450, 200 );
}

seitenspiegel::~seitenspiegel()
{
    delete quitButton;
    delete gridLayout;
    delete lbl_docSize;
    delete spx_docSize;
    delete rdb_min;
    delete rdb_max;
    delete sld_BlockSize;
    delete lbl_Ergebnis;
    delete txt_ergebnis;
    delete btn_calc;
}

void seitenspiegel::on_rdb_min( bool t )
{
    if(rdb_min->isChecked()){
        minmax_rdb = rdb_min;
        txt_rdb = "mi&n. ";
        minmax = &minBlockSize;
        sld_BlockSize->setValue( minBlockSize );
    }
    sld_BlockSize->setFocus();
}

void seitenspiegel::on_rdb_max( bool t )
{
    if(rdb_max->isChecked()){
        minmax_rdb = rdb_max;
        txt_rdb = "ma&x. ";
        minmax = &maxBlockSize;
        sld_BlockSize->setValue( maxBlockSize );
    }
    sld_BlockSize->setFocus();
}

void seitenspiegel::on_sld_BlockSize(int v)
{
    *minmax = v;
    minmax_rdb->setText( txt_rdb + QString::number( v ) + tr(" Blatt / Block") );
    if(v<minBlockSize){
        minBlockSize = v;
        rdb_min->setText( tr("mi&n. ") + QString::number( v ) + tr(" Blatt / Block") );
    }
    if(v > maxBlockSize){
        maxBlockSize = v;
        rdb_max->setText( tr("ma&x. ") + QString::number( v ) + tr(" Blatt / Block") );
    }
    txt_ergebnis->setPlainText("");
}

void seitenspiegel::on_spx_docSize(int v)
{
    docSize = v;
    txt_ergebnis->setPlainText("");
}

void seitenspiegel::on_btn_calc()
{
    int countBlocks, bestDiff, tmpmax, tmplast, curDiff;
    double ds, cb, maxbs, lastBlockSize, restSheets;
    int spb, stw, a, e;
    
    ds = docSize;
    maxbs = maxBlockSize;
    lastBlockSize = 0;
    txt_ergebnis->setPlainText("");
    bestDiff = maxBlockSize;
    tmpmax  = maxBlockSize;
    tmplast = int(lastBlockSize);

    // Optimizing Blocksize ...
    while(minBlockSize < maxBlockSize){
        countBlocks = (int) floor(ds/(maxbs*4));
        cb = countBlocks;
        restSheets  = docSize - (countBlocks * maxBlockSize *4);
        if (restSheets > 0){
            lastBlockSize = (int) ceil(restSheets/4);
            curDiff = maxBlockSize - int(lastBlockSize);
            if (curDiff < bestDiff){
                bestDiff = curDiff;
                tmpmax   = maxBlockSize;
                tmplast  = int(lastBlockSize);
            }
            maxBlockSize--;
            maxbs = maxBlockSize;
        } else {
            maxBlockSize = minBlockSize;
            tmpmax   = maxBlockSize;
            tmplast  = int(lastBlockSize);
        }
    }
    maxBlockSize  = tmpmax;
    lastBlockSize = tmplast;
    spb = maxBlockSize * 4;
    stw = maxBlockSize * 2;
    countBlocks = (int) floor(docSize/spb);
    restSheets  = docSize - (countBlocks * spb);
    if (restSheets && !lastBlockSize){
        lastBlockSize = ceil( restSheets/4);
    }
    txt_ergebnis->insertPlainText(""+QString::number(countBlocks) + tr(" Block a ") + QString::number(maxBlockSize) + tr(" Blatt, ") + QString::number(spb) + tr(" Seiten/Block => ") + QString::number(countBlocks*spb) + "\n");
    if (restSheets > 0){
        txt_ergebnis->insertPlainText(tr("1 Block a ") + QString::number(lastBlockSize) + tr(" Blatt, ") + QString::number(restSheets) + tr(" Seiten\n"));
    }
    txt_ergebnis->insertPlainText("-------------\n");
    for (int i=0; i < countBlocks; i++){
        a = i * spb;
        e = a + spb;
        printBlock(i,a,e,stw,0);
    }
    if (restSheets > 0){
        txt_ergebnis->insertPlainText(tr("\nletzter Block (") + QString::number(lastBlockSize) + tr(" Blatt):"));
        a = countBlocks * spb;
        e = a + (int(lastBlockSize) * 4);
        printBlock(countBlocks,a,e,int(lastBlockSize*2),docSize);
    }
    
    txt_ergebnis->insertPlainText("\n---------------\n");
}

void seitenspiegel::printBlock(int n, int a, int e, int s, int z)
{
    int l, r;
    txt_ergebnis->insertPlainText(tr("\nBlock: ") + QString::number(n+1) + tr(" ( Dokumentseite ") + QString::number(a+1) 
                                + tr(" bis ") + QString::number(z?z:e) + ")");
    txt_ergebnis->insertPlainText(tr("\nVorderseite:"));
    if (z > 0){
        for(int i=1; i<s; i+=2){
            l = a + i;
            r = 1 + e -i;
            if (l > z) { l=0; }
            if (r > z) { r=0; }
            txt_ergebnis->insertPlainText(" "+QString::number(r)+","+QString::number(l)+" ,");
        }
        txt_ergebnis->insertPlainText( tr("\nRueckseite :"));
        for(int i=s; i >= 2; i-=2){
            l = a + i;
            r = 1 + e -i;
            if (l > z) { l=0; }
            if (r > z) { r=0; }
            txt_ergebnis->insertPlainText(" "+QString::number(l)+","+QString::number(r)+" ,");
        }
    }else{
        for (int i=1; i<s; i+=2){
            txt_ergebnis->insertPlainText(" "+QString::number(1+e-i)+","+QString::number(a+i)+" ,");
        }
        txt_ergebnis->insertPlainText( tr("\nRueckseite :"));
        for (int i=s; i>=2; i-=2){
            txt_ergebnis->insertPlainText(" "+QString::number(a+i)+","+QString::number(1+e-i)+" ,");
        }
    }
    txt_ergebnis->insertPlainText("\n");
}