/* -*- Mode: C++ -*-
   KDChart - a multi-platform charting engine
   */

/****************************************************************************
 ** Copyright (C) 2001-2007 Klarälvdalens Datakonsult AB.  All rights reserved.
 **
 ** This file is part of the KD Chart library.
 **
 ** This file may be used under the terms of the GNU General Public
 ** License versions 2.0 or 3.0 as published by the Free Software
 ** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
 ** included in the packaging of this file.  Alternatively you may (at
 ** your option) use any later version of the GNU General Public
 ** License if such license has been publicly approved by
 ** Klarälvdalens Datakonsult AB (or its successors, if any).
 ** 
 ** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
 ** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
 ** A PARTICULAR PURPOSE. Klarälvdalens Datakonsult AB reserves all rights
 ** not expressly granted herein.
 ** 
 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 **
 **********************************************************************/

#include "KDChartPalette.h"
#include <QBrush>
#include <QVector>

#include <KDABLibFakes>

using namespace KDChart;

namespace {

    static Palette makeDefaultPalette() {
        Palette p;

        p.addBrush( Qt::red );
        p.addBrush( Qt::green );
        p.addBrush( Qt::blue );
        p.addBrush( Qt::cyan );
        p.addBrush( Qt::magenta );
        p.addBrush( Qt::yellow );
        p.addBrush( Qt::darkRed );
        p.addBrush( Qt::darkGreen );
        p.addBrush( Qt::darkBlue );
        p.addBrush( Qt::darkCyan );
        p.addBrush( Qt::darkMagenta );
        p.addBrush( Qt::darkYellow );

        return p;
    }

    static Palette makeSubduedPalette() {
        Palette p;

        p.addBrush( QColor( 0xe0,0x7f,0x70 ) );
        p.addBrush( QColor( 0xe2,0xa5,0x6f ) );
        p.addBrush( QColor( 0xe0,0xc9,0x70 ) );
        p.addBrush( QColor( 0xd1,0xe0,0x70 ) );
        p.addBrush( QColor( 0xac,0xe0,0x70 ) );
        p.addBrush( QColor( 0x86,0xe0,0x70 ) );
        p.addBrush( QColor( 0x70,0xe0,0x7f ) );
        p.addBrush( QColor( 0x70,0xe0,0xa4 ) );
        p.addBrush( QColor( 0x70,0xe0,0xc9 ) );
        p.addBrush( QColor( 0x70,0xd1,0xe0 ) );
        p.addBrush( QColor( 0x70,0xac,0xe0 ) );
        p.addBrush( QColor( 0x70,0x86,0xe0 ) );
        p.addBrush( QColor( 0x7f,0x70,0xe0 ) );
        p.addBrush( QColor( 0xa4,0x70,0xe0 ) );
        p.addBrush( QColor( 0xc9,0x70,0xe0 ) );
        p.addBrush( QColor( 0xe0,0x70,0xd1 ) );
        p.addBrush( QColor( 0xe0,0x70,0xac ) );
        p.addBrush( QColor( 0xe0,0x70,0x86 ) );

        return p;
    }

    static Palette makeRainbowPalette() {
        Palette p;

        p.addBrush( QColor(255,  0,196) );
        p.addBrush( QColor(255,  0, 96) );
        p.addBrush( QColor(255, 128,64) );
        p.addBrush( Qt::yellow );
        p.addBrush( Qt::green );
        p.addBrush( Qt::cyan );
        p.addBrush( QColor( 96, 96,255) );
        p.addBrush( QColor(160,  0,255) );
        for( int i = 8 ; i < 16 ; ++i )
            p.addBrush( p.getBrush(i-8).color().light(), i );

        return p;
    }

}

#define d d_func()

class Palette::Private
{
public:
    explicit Private() {}
    ~Private() {}

    QVector<QBrush> brushes;
};

const Palette& Palette::defaultPalette()
{
    static const Palette palette = makeDefaultPalette();
    return palette;
}

const Palette& Palette::subduedPalette()
{
    static const Palette palette = makeSubduedPalette();
    return palette;
}

const Palette& Palette::rainbowPalette()
{
    static const Palette palette = makeRainbowPalette();
    return palette;
}

Palette::Palette( QObject *parent )
  : QObject( parent ), _d( new Private )
{

}

Palette::~Palette()
{
    delete _d; _d = 0;
}



Palette::Palette( const Palette& r )
    : QObject(), _d( new Private( *r.d ) )
{
}

Palette& Palette::operator=( const Palette& r )
{
    Palette copy( r );
    copy.swap( *this );

    // emit changed() ?
    return *this;
}

bool Palette::isValid() const
{
  return d->brushes.size() >= 1;
}

int Palette::size() const
{
  return d->brushes.size();
}

void Palette::addBrush( const QBrush& brush, int position )
{
  if ( position < 0 || position >= size() ) {
    d->brushes.append( brush );
  } else {
    d->brushes.insert( position, brush );
  }
  emit changed();
}

QBrush Palette::getBrush( int position ) const
{
  if ( !isValid() ) return QBrush();
  return d->brushes.at( position % size() );
}

void Palette::removeBrush( int position )
{
  if ( position < 0 || position >= size() ) return;
  d->brushes.remove( position );
  emit changed();
}

