/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

// File MvIcon
// Gilberto Camara - ECMWF Apr 97
//
// .NAME:
//  MvIcon
//
// .AUTHOR:
//  Gilberto Camara and Fernando Ii
//
// .SUMMARY:
//  Describes the MvIcon class, a base class
//  for the various types of icons in PlotMod
//
// .CLIENTS:
//  Presentable, Matcher
//
// .RESPONSABILITY:
//  This class will provide support for dealing with
//  the different types of Icons in PlotMod.
//
// .COLLABORATORS:
//  MvIconRep
//
// .ASCENDENT:
//
// .DESCENDENT:
//
//
// .REFERENCES:
//  This "reference counted" class is based on the
//  "handle/body" C++ idiom, described in Coplien(1992), pg. 58.
//
#pragma once

#include "MvRequest.h"
#include "ObjectInfo.h"

class MvIcon;

// --- This is the handle class - MvIconRep

class MvIconRep
{
    friend class MvIcon;

private:
    // Constructors
    MvIconRep();
    MvIconRep(const std::string& iconName, const std::string& iconClass);
    MvIconRep(const MvRequest& inRequest, bool idSave = false);
    MvIconRep(bool);

    // Destructor
    ~MvIconRep() = default;

    // Copy Constructor and Operator =
    MvIconRep& operator=(const MvIconRep& mvIconRep);
    MvIconRep(const MvIconRep& mvIconRep);

    static int iconNextId_;
    int iconId_{0};
    int parentId_{0};

    std::string iconName_;
    std::string iconFullPath_;
    std::string iconClass_;

    MvRequest myRequest_;

    MvRequest svcRequest_;

    int refCount_{0};  // reference counter

    // Layer info
    bool visibility_{true};
    int transparency_{0};  // 0 - 100
    int order_{-1};        // stacking order: 0, 1, ...
};


class MvIcon
{
public:
    // Contructors
    MvIcon();
    MvIcon(const std::string& iconName, const std::string& iconClass);
    MvIcon(bool);

    // Default constructor
    // Builds an icon from Request
    // Initialises the reference counter
    MvIcon(const MvRequest& inRequest, bool idSave = false);

    // Copy constructor
    // copies the representation pointer
    // increments the reference counter
    MvIcon(const MvIcon& inIcon);

    // Operator =
    // Copies the representation pointer
    // Decrements the reference counter of the current object
    // Increments the reference counter for the new object
    MvIcon& operator=(const MvIcon& inIcon);

    // Destructor
    ~MvIcon();

    // Change name
    void Rename(const std::string& newName)
    {
        ptrIconRep_->iconName_ = newName;
    }

    // Save the request associated to the icon
    void SaveRequest(const MvRequest&);

    // File name
    const char* PathName() const
    {
        return ptrIconRep_->iconFullPath_.c_str();
    }
    std::string& sPathName() const
    {
        return ptrIconRep_->iconFullPath_;
    }

    // Icon full name
    const char* FullName() const
    {
        return ptrIconRep_->iconName_.c_str();
    }
    std::string& sFullName() const
    {
        return ptrIconRep_->iconName_;
    }

    // Icon short name
    const char* IconName() const
    {
        return ptrIconRep_->iconName_.c_str();
    }
    std::string& sIconName() const
    {
        return ptrIconRep_->iconName_;
    }

    // Icon class
    const char* IconClass() const
    {
        return ptrIconRep_->iconClass_.c_str();
    }
    std::string& sIconClass() const
    {
        return ptrIconRep_->iconClass_;
    }

    // Icon MetviewUI class. It can be different from iconClass() value,
    // because MetviewUI retrieves this information from the icon file.
    // I think that the method IconClass should be renamed to
    // IconVerb (Fernando, 01/00)
    std::string IconMetUIClass() const
    {
        return (const char*)ObjectInfo::IconClass(Request());
    }

    // Retrieves the associated request
    // blayer = false : do not provide layer info
    MvRequest Request() const;

    // Handles the id
    int Id() const
    {
        return ptrIconRep_->iconId_;
    }

    // Overloaded operator == , checks for the same path and name
    friend bool operator==(MvIcon& a, MvIcon& b);

    void ParentId(int parentId)
    {
        ptrIconRep_->parentId_ = parentId;
    }

    int ParentId()
    {
        return ptrIconRep_->parentId_;
    }

    // Save the request associated to the icon
    void SvcRequest(const MvRequest& svcRequest)
    {
        ptrIconRep_->svcRequest_ = svcRequest;
    }

    MvRequest SvcRequest() const;

    // Layer information
    void Visibility(bool b) { ptrIconRep_->visibility_ = b; }
    void Transparency(int n) { ptrIconRep_->transparency_ = n; }
    void StackingOrder(int n) { ptrIconRep_->order_ = n; }
    bool Visibility() { return ptrIconRep_->visibility_; }
    int Transparency() { return ptrIconRep_->transparency_; }
    int StackingOrder() { return ptrIconRep_->order_; }

private:
    MvIconRep* ptrIconRep_{nullptr};
};
