/*******************************************************************************
** Qt Advanced Docking System
** Copyright (C) 2017 Uwe Kindler
** 
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
** 
** This library 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
** Lesser General Public License for more details.
** 
** You should have received a copy of the GNU Lesser General Public
** License along with this library; If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/


//============================================================================
/// \file   DockSplitter.cpp
/// \author Uwe Kindler
/// \date   24.03.2017
/// \brief  Implementation of CDockSplitter
//============================================================================

//============================================================================
//                                   INCLUDES
//============================================================================
#include "DockSplitter.h"

#include <QDebug>
#include <QChildEvent>
#include <QVariant>
#include "DockAreaWidget.h"

namespace ads
{
/**
 * Private dock splitter data
 */
struct DockSplitterPrivate
{
	CDockSplitter* _this;
	int VisibleContentCount = 0;
	QList<int> SavedSizes;

	DockSplitterPrivate(CDockSplitter* _public) : _this(_public) {}
};

//============================================================================
CDockSplitter::CDockSplitter(QWidget *parent)
	: QSplitter(parent),
	  d(new DockSplitterPrivate(this))
{
    setProperty("ads-splitter", QVariant(true));
	setChildrenCollapsible(false);
	
	// Connect to size change signals to maintain size history
	connect(this, &QSplitter::splitterMoved, this, &CDockSplitter::updateSavedSizes);
	
	// Install event filter to catch hide/show events
	installEventFilter(this);
}


//============================================================================
CDockSplitter::CDockSplitter(Qt::Orientation orientation, QWidget *parent)
	: QSplitter(orientation, parent),
	  d(new DockSplitterPrivate(this))
{	
	// Connect to size change signals to maintain size history
	connect(this, &QSplitter::splitterMoved, this, &CDockSplitter::updateSavedSizes);
	
	// Install event filter to catch hide/show events
	installEventFilter(this);
}

//============================================================================
CDockSplitter::~CDockSplitter()
{
    ADS_PRINT("~CDockSplitter");
	delete d;
}


//============================================================================
bool CDockSplitter::hasVisibleContent() const
{
	// TODO Cache or precalculate this to speed up
	for (int i = 0; i < count(); ++i)
	{
		if (!widget(i)->isHidden())
		{
			return true;
		}
	}

	return false;
}


//============================================================================
QWidget* CDockSplitter::firstWidget() const
{
	return (count() > 0) ? widget(0) : nullptr;
}


//============================================================================
QWidget* CDockSplitter::lastWidget() const
{
	return (count() > 0) ? widget(count() - 1) : nullptr;
}

//============================================================================
bool CDockSplitter::isResizingWithContainer() const
{
    for (auto area : findChildren<CDockAreaWidget*>())
    {
        if(area->isCentralWidgetArea())
        {
            return true;
        }
    }

    return false;
}

//============================================================================
void CDockSplitter::saveAndSetSizes(const QList<int>& sizes)
{
    d->SavedSizes = sizes;
    QSplitter::setSizes(sizes);
}

//============================================================================
QList<int> CDockSplitter::sizesForStateSaving() const
{
    auto currentSizes = sizes();
    
    // If all current sizes are valid (none are 0), use them and update cache
    bool hasZeroSizes = false;
    for (int size : currentSizes) {
        if (size == 0) {
            hasZeroSizes = true;
            break;
        }
    }
    
    if (!hasZeroSizes) {
        // Update saved sizes with current valid sizes
        d->SavedSizes = currentSizes;
        return currentSizes;
    }
    
    // Try to use saved sizes from private data
    if (!d->SavedSizes.isEmpty() && d->SavedSizes.count() == currentSizes.count()) {
        QList<int> sizesForSaving = currentSizes;
        for (int i = 0; i < sizesForSaving.count(); ++i) {
            if (currentSizes[i] == 0 && d->SavedSizes[i] > 0) {
                sizesForSaving[i] = d->SavedSizes[i];
            }
        }
        return sizesForSaving;
    }
    
    
    // Fallback: return current sizes even if some are 0
    return currentSizes;
}

//============================================================================
void CDockSplitter::updateSavedSizes()
{
    auto currentSizes = sizes();
    
    // Only update if we have valid sizes (no zeros)
    bool hasValidSizes = true;
    for (int size : currentSizes) {
        if (size <= 0) {
            hasValidSizes = false;
            break;
        }
    }
    
    if (hasValidSizes) {
        d->SavedSizes = currentSizes;
    }
}

//============================================================================
bool CDockSplitter::eventFilter(QObject* obj, QEvent* event)
{
    if (obj == this) {
        if (event->type() == QEvent::Hide) {
            // Store current sizes before hiding to preserve them
            updateSavedSizes();
        }
    }
    return QSplitter::eventFilter(obj, event);
}

} // namespace ads

//---------------------------------------------------------------------------
// EOF DockSplitter.cpp
