 
//OpenSCADA system module DAQ.DCON file: DCON_client.h
/***************************************************************************
 *   Copyright (C) 2008-2011 by Almaz Karimov                              *
 *		   2008-2014 by Roman Savochenko, rom_as@oscada.org        *
 *                                                                         *
 *   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; version 2 of the License.               *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef OWEN_CLIENT_H
#define OWEN_CLIENT_H

#include <tcontroller.h>
#include <ttypedaq.h>
#include <tparamcontr.h>

#include <string>
#include <vector>
#include <map>

#undef _
#define _(mess) mod->I18N(mess)

#define MaxLenReq 200

using std::string;
using std::vector;
using std::map;
using namespace OSCADA;

namespace Owen
{

//******************************************************
//* TMdPrm                                             *
//******************************************************
class TMdContr;

class TMdPrm : public TParamContr
{
    public:
	//Methods
	TMdPrm( string name, TTypeParam *tp_prm );
	~TMdPrm( );

	void enable( );
	void disable( );

	TElem &elem( )		{ return p_el; }
	TMdContr &owner( );

	//Attributes
	TElem	p_el;		//Work atribute elements
	int64_t	&mod_addr;	//Module address
	char	&addr_11bit;	//DCON CRC control mode
	ResString comm_err;
	bool end_prm;
	
	struct auxData {
		union owdb {
			char c[7];							//	|c7	|c6	|c5	|c4	|c3	|c2	|c1	|c0	|
			long long int lli;					//	|				lli				|
			struct { long int li0, li1; } ;		//	|		li1		|		li0		|
			struct { int i3, i2, i1, i0; } ;	//	|	i3	|	i2	|	i1	|	i0	|
			struct { float f1, f0; } ;			//	|		f1		|		f0		|
			double d;							//	|				d				|
		} db;
		char ftype;
		string err;
		string readReq;
		string writeReq;
		string respReq;
		TFld::Type type;
	} data, data0;
	std::map<string, auxData> attr;
	std::map<string, auxData>::iterator it;
/*	class auxAttr {
		public:
		std::map<string, auxData> locmap;
		std::map<string, auxData>::iterator it;
		std::map<string, auxData>::iterator &find( string str ) { locmap.find(str); }
		std::map<string, auxData>::iterator &begin() { locmap.begin(); }
		std::map<string, auxData>::iterator &end() { locmap.end(); }
		//pair< std::map<string, auxData>::iterator ,bool> &emplace(string str, auxData data) { locmap.emplace(str, data); }
		void add(const string, const  auxData);
		auxAttr ();
	} attr;	*/

    protected:
	//Methods
	bool cfgChange( TCfg &co, const TVariant &pc );
	void cntrCmdProc( XMLNode *opt );	//Control interface command process

    private:
	//Methods
	void postEnable( int flag );
	void vlGet( TVal &vo );
	void vlSet( TVal &vo, const TVariant &vl, const TVariant &pvl );
	void vlArchMake( TVal &val );
};

//******************************************************
//* TMdContr                                           *
//******************************************************
class TMdContr: public TController
{
    public:
	//Methods
	TMdContr( string name_c, const string &daq_db, TElem *cfgelem);
	~TMdContr( );

	string getStatus( );

	double	period( )	{ return mPer; }
	string	cron( )		{ return cfg("SCHEDULE").getS(); }
	int	prior( )	{ return mPrior; }
	string	addr( )		{ return mAddr; }

	AutoHD<TMdPrm> at( const string &nm )	{ return TController::at(nm); }
	void prmEn( const string &id, bool val );

	unsigned hashCRC( string req, bool hash );
	string OwenReq( string &pdu );
	string attrName( string attr );
	string netName( string name, string *err );
	bool formPDU( int addr, string netName, bool addr11bit, string *pdu, string *err );
	char char4hash( char ch, char next );
	float ieee2float( string data );
	float b2float( string data );


    protected:
	//Methods
	void load_( );
	void disable_( );
	void start_( );
	void stop_( );
	void cntrCmdProc( XMLNode *opt );	//Control interface command process
	bool cfgChange( TCfg &co, const TVariant &pc );

    private:
	//Methods
	TParamContr *ParamAttach( const string &name, int type );
	static void *Task( void *icntr );

	//Attributes
	Res	en_res, req_res;		//Resource for enable params and request values
	TCfg	&mAddr;				//Transport device address
	int64_t	&mPerOld,			//Acquisition task (seconds)
		&mPrior,			//Process task priority
		&connTry;			//Connections try

	bool	prc_st,				//Process task active
		call_st,        		//Calc now stat
		endrun_req;			//Request to stop of the Process task
	vector< AutoHD<TMdPrm> >  p_hd;

	double	mPer, tm_gath;			//Gathering time
};

//*************************************************
//* TTpContr                                      *
//*************************************************
class TTpContr: public TTypeDAQ
{
    public:
	//Methods
	TTpContr( string name );
	~TTpContr( );

    protected:
	//Methods
	void load_( );
	void save_( );

	bool redntAllow( )	{ return true; }

    private:
	//Methods
	void postEnable( int flag );
	TController *ContrAttach( const string &name, const string &daq_db );
};

extern TTpContr *mod;

} //End namespace

#endif //OWEN_CLIENT_H
