/***************************** 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 Device
// Gilberto Camara - ECMWF Sep 97
//
// .NAME:
//  Device
//
// .AUTHOR:
//  Gilberto Camara and Fernando Ii
//
// .SUMMARY:
//  Describes the Device class, which is the
//  object which describes the media in which
//  PlotMod will produce its outout
//
//  Each superpage is associated with ONE device, which is
//  instatiated and initialised by the SuperPage constructor
//
// .CLIENTS:
//  SuperPage
//
//
// .RESPONSABILITIES:
//  A device may correspond either to a XWindow Interface
//  (which is the default) or to a paper sheet
//
//  After the superpage creates a device, it calls the "initialise"
//  method, which will visit the superpage and its children and will
//  create the appropriate drawing areas ("canvas").
//
//
// .COLLABORATORS:
//  MvRequest, Canvas, GraphicsEngine
//
//
// .BASE CLASS:
//  (none)
//
// .DERIVED CLASSES:
//  XDevice, PSDevice
//
// .REFERENCES:
//   This template factory class which creates devices
//   is based on the "Factory" pattern (see
//  "Design Patterns" book, page 107).
//
//  The templated factory is based on the idea of "traits"
//  described in the article "A New and Useful Template Technique: "Traits"
//  by Nathan Myers, included in the "C++ Gems" book
//  (see also Stroustrup, 3rd. edition, page 580ff).
//
//  The interaction between a Device and its associated Presentable is
//  based on the "Visitor" pattern ("Design Patterns", page 331)
//
#pragma once

#include <Factory.hpp>
#include <MvRequest.h>
#include "Visitor.h"

class Device;
class Presentable;

// Class Device Factory - clones a new Device on Request
struct DeviceFactoryTraits
{
    using Type = Device;
    using Parameter = const MvRequest&;
    static Cached FactoryName(Parameter);
    static Type* DefaultObject(Parameter);
};

class DeviceFactory : public Factory<DeviceFactoryTraits>
{
public:
    DeviceFactory(const Cached& name) :
        Factory<DeviceFactoryTraits>(name) {}
};


class Device : public Visitor
{
public:
    // Contructors
    Device(const MvRequest& deviceRequest);

    // Destructor
    ~Device() override;

    // Visitor methods
    virtual void Initialise(Presentable& p);

    // Class members
    const MvRequest& DeviceRequest() const
    {
        return deviceRequest_;
    }

#if 0
	Cached DeviceType ();

  //	operator FILE*() const 
  //		{ return filePtr_; }

	Cached FileName() const
		{ return outFileName_; }

	Cached TmpFileName() const
		{ return outTmpFileName_; }

	virtual Cached PrinterName() const
		{ return Cached (""); }

#endif

    // Static method
    static MvRequest CreateRequest(const MvRequest&);

protected:
    // Members
    MvRequest deviceRequest_;

    Cached outFileName_;  // name of the output file

    Cached outTmpFileName_;  // name of the temporary output file

private:
    // No copy allowed
    Device(const Device&);
    Device& operator=(const Device&)
    {
        return *this;
    }
};
