//------------------------------------------------------------------------------
// emLook.h
//
// Copyright (C) 2005-2010,2014 Oliver Hamann.
//
// Homepage: http://eaglemode.sourceforge.net/
//
// This program is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License version 3 as published by the
// Free Software Foundation.
//
// 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 version 3 for
// more details.
//
// You should have received a copy of the GNU General Public License version 3
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------

#ifndef emLook_h
#define emLook_h

#ifndef emPanel_h
#include <emCore/emPanel.h>
#endif


//==============================================================================
//=================================== emLook ===================================
//==============================================================================

class emLook {

public:

        // Class for the look of toolkit panels. Currently, the look consists of
        // a set of colors only. Objects of this class have copy-on-write
        // behavior.

        emLook();
                // Construct a default look.

        emLook(const emLook & look);
                // Construct a copied look.

        ~emLook();
                // Destructor.

        emLook & operator = (const emLook & look);
                // Copy a look.

        bool operator == (const emLook & look) const;
        bool operator != (const emLook & look) const;
                // Compare two looks.

        void Apply(emPanel * panel, bool recursively) const;
                // Apply this look to a panel or to all panels in a sub-tree.
                // Applying actually works for panels of class emBorder and
                // its derivatives only, but the recursion is not stopped by
                // other panel classes. However, the recursion can be stopped by
                // an overloaded implementation of emBorder::SetLook.
                // Arguments:
                //   panel       - The panel.
                //   recursively - Whether to recurse ancestor panels.

        emColor GetBgColor() const;
        emColor GetFgColor() const;
        void SetBgColor(emColor bgColor);
        void SetFgColor(emColor fgColor);
                // Get/set back- and foreground colors of borders, labels,
                // groups and similar things.

        emColor GetButtonBgColor() const;
        emColor GetButtonFgColor() const;
        void SetButtonBgColor(emColor buttonBgColor);
        void SetButtonFgColor(emColor buttonFgColor);
                // Get/set back- and foreground colors of button faces.

        emColor GetInputBgColor() const;
        emColor GetInputFgColor() const;
        emColor GetInputHlColor() const;
        void SetInputBgColor(emColor inputBgColor);
        void SetInputFgColor(emColor inputFgColor);
        void SetInputHlColor(emColor inputHlColor);
                // Get/set background, foreground and highlight (=selection)
                // colors of editable data fields.

        emColor GetOutputBgColor() const;
        emColor GetOutputFgColor() const;
        emColor GetOutputHlColor() const;
        void SetOutputBgColor(emColor outputBgColor);
        void SetOutputFgColor(emColor outputFgColor);
        void SetOutputHlColor(emColor outputHlColor);
                // Get/set background, foreground and highlight (=selection)
                // colors of read-only data fields.

        unsigned int GetDataRefCount() const;
                // Get number of references to the internal data of this object.

        void MakeNonShared();
                // This must be called before handing the look to another
                // thread.

private:

        void DeleteData();
        void MakeWritable();

        struct SharedData {
                SharedData();
                SharedData(const SharedData & sd);
                unsigned int RefCount;
                emColor BgColor;
                emColor FgColor;
                emColor ButtonBgColor;
                emColor ButtonFgColor;
                emColor InputBgColor;
                emColor InputFgColor;
                emColor InputHlColor;
                emColor OutputBgColor;
                emColor OutputFgColor;
                emColor OutputHlColor;
        };

        SharedData * Data;

        static SharedData DefaultData;
};

#ifndef EM_NO_DATA_EXPORT
inline emLook::emLook()
{
        Data=&DefaultData;
}
#endif

inline emLook::emLook(const emLook & look)
{
        Data=look.Data;
        Data->RefCount++;
}

inline emLook::~emLook()
{
        if (!--Data->RefCount) DeleteData();
}

inline emLook & emLook::operator = (const emLook & look)
{
        look.Data->RefCount++;
        if (!--Data->RefCount) DeleteData();
        Data=look.Data;
        return *this;
}

inline bool emLook::operator != (const emLook & look) const
{
        return !(*this==look);
}

inline emColor emLook::GetBgColor() const
{
        return Data->BgColor;
}

inline emColor emLook::GetFgColor() const
{
        return Data->FgColor;
}

inline emColor emLook::GetButtonBgColor() const
{
        return Data->ButtonBgColor;
}

inline emColor emLook::GetButtonFgColor() const
{
        return Data->ButtonFgColor;
}

inline emColor emLook::GetInputBgColor() const
{
        return Data->InputBgColor;
}

inline emColor emLook::GetInputFgColor() const
{
        return Data->InputFgColor;
}

inline emColor emLook::GetInputHlColor() const
{
        return Data->InputHlColor;
}

inline emColor emLook::GetOutputBgColor() const
{
        return Data->OutputBgColor;
}

inline emColor emLook::GetOutputFgColor() const
{
        return Data->OutputFgColor;
}

inline emColor emLook::GetOutputHlColor() const
{
        return Data->OutputHlColor;
}

inline void emLook::MakeNonShared()
{
        MakeWritable();
}


#endif