/******************************************************************************
    SlideEffect_Blinds: Blinds effect.
    Copyright (C) 2011-2013 Wang Bin <wbsecg1@gmail.com>

	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 "slideeffect.h"
#include <time.h>

static const QString kBlindsBottomToTop = "blinds_bottom_to_top";
static const QString kBlindsLeftToRight = "blinds_left_to_right";
static const QString kBlindsRightToLeft = "blinds_right_to_left";
static const QString kBlindsTopToBottom = "blinds_top_to_bottom";
class SlideEffect_Blinds : public SlideEffect
{
public:
    virtual bool prepare();
    virtual QVector<EffectId> supportedTypes() const {
        return QVector<EffectId>() << kBlindsBottomToTop << kBlindsLeftToRight
                << kBlindsRightToLeft << kBlindsTopToBottom;
    }
protected:
    virtual bool prepareFrameAt(int frame);
private:
    //void calculateRegion_Random(qreal k); //default
    void calculateRegion_BottomToTop(qreal k);
    void calculateRegion_LeftToRight(qreal k);
    void calculateRegion_RightToLeft(qreal k);
    void calculateRegion_TopToBottom(qreal k);

    typedef void (SlideEffect_Blinds::*calculateRegion_Func)(qreal);
    calculateRegion_Func calculateRegion_ptr;

    int leafs;
    int leaf_width;
};

REGISTER_EFFECTS(SlideEffect_Blinds)

bool SlideEffect_Blinds::prepare()
{
    SlideEffect::prepare(); //Important!!!
    if (effect_type == kBlindsBottomToTop)
        calculateRegion_ptr = &SlideEffect_Blinds::calculateRegion_BottomToTop;
    else if (effect_type == kBlindsLeftToRight)
        calculateRegion_ptr = &SlideEffect_Blinds::calculateRegion_LeftToRight;
    else if (effect_type == kBlindsRightToLeft)
        calculateRegion_ptr = &SlideEffect_Blinds::calculateRegion_RightToLeft;
    else if (effect_type == kBlindsTopToBottom)
        calculateRegion_ptr = &SlideEffect_Blinds::calculateRegion_TopToBottom;
	else
        calculateRegion_ptr = &SlideEffect_Blinds::calculateRegion_TopToBottom; //calculateRegion_Random

	qsrand(time(0));
	leafs = qrand()%13 + 2;
	qDebug("leafs=%d", leafs);
    if (effect_type==kBlindsRightToLeft || effect_type==kBlindsRightToLeft) {
		leaf_width = width/leafs + 1; //Must plus 1! Or the final frame_image may have blanks
	} else {
		leaf_width = height/leafs + 1;
	}

	return true;
}

bool SlideEffect_Blinds::prepareFrameAt(int frame)
{
	if (isEndFrame(frame))
		return false;
	qreal k = easing_.valueForProgress(progress_);
	(this->*calculateRegion_ptr)(k);
	current_clip_region = QRegion(0, 0, width, height) - next_clip_region;
	return true;
}

void SlideEffect_Blinds::calculateRegion_BottomToTop(qreal k)
{
	next_clip_region = QRegion();
	for (int i=0;i<leafs;next_clip_region += QRegion(0, (i+++1.0-k)*leaf_width, width, leaf_width*k));
}

//Have some bugs! Pictures are not show completely
void SlideEffect_Blinds::calculateRegion_LeftToRight(qreal k)
{
	next_clip_region = QRegion();
	for (int i=0;i<leafs;next_clip_region += QRegion(i++*leaf_width, 0, leaf_width*k, height));
}

void SlideEffect_Blinds::calculateRegion_RightToLeft(qreal k)
{
	next_clip_region = QRegion();
	for (int i=0;i<leafs;next_clip_region += QRegion((i+++1.0-k)*leaf_width, 0, leaf_width*k, height));
}

void SlideEffect_Blinds::calculateRegion_TopToBottom(qreal k)
{
	next_clip_region = QRegion();
	for (int i=0;i<leafs;next_clip_region += QRegion(0, i++*leaf_width, width, leaf_width*k));
}
