/***************************** 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 *************************************/

#ifndef XMText_H
#include "XMText.h"
#endif

#ifndef MacroEditor_H
#include "MacroEditor.h"
#endif

#ifndef EditorFactory_H
#include "EditorFactory.h"
#endif

#ifndef IconObject_H
#include "IconObject.h"
#endif

#ifndef Log_H
#include "Log.h"
#endif

#ifndef EditorButton_H
#include "EditorButton.h"
#endif

#ifndef IconFactory_H
#include "IconFactory.h"
#endif


#ifndef Folder_H
#include "Folder.h"
#endif

#ifndef Action_H
#include "Action.h"
#endif

#ifndef Request_H
#include "Request.h"
#endif

#ifndef IconClass_H
#include "IconClass.h"
#endif

#ifndef OutputDrawer_H
#include "OutputDrawer.h"
#endif

#include "Tab.h"

#ifndef MacroRunTask_H
#include "MacroRunTask.h"
#endif


MacroEditor::MacroEditor(const IconClass& name,const string& kind):
	BaseTextEditor(name,kind)
{

}

MacroEditor::~MacroEditor()
{
}

void MacroEditor::output(Widget w)
{
	output_ = w;
}


void MacroEditor::merge(IconObject* o)
{
	XMText text(text_);
	Path temp(::marstmp());

	char buf[1024];
	sprintf(buf,"$METVIEW_BIN/mvimport \"%s\" %s",
		o->fullName().c_str(),
		temp.str().c_str());

	system(buf);
	text.load(temp,true);

	temp.remove();
}

void MacroEditor::replace(IconObject* o)
{
	XMText text(text_);
	text.clear();
	merge(o);
}

void MacroEditor::run()
{
	start("prepare",false);
}

void MacroEditor::trace()
{
	start("prepare",true);
}

void MacroEditor::beautify()
{
	Path tmp1(::marstmp());
	Path tmp2(::marstmp());

	XMText text(text_);
	text.save(tmp1);

	XMText out(output_);
	out.clear();

	char buf[1024];
	sprintf(buf,"$METVIEW_BIN/beautify -b -f \"%s\" -g \"%s\"",
		tmp1.str().c_str(),
		tmp2.str().c_str());

	if(system(buf) == 0)
	{
		progress("Macro beautified");
		text.load(tmp2);
	}
	else
		check();

	tmp1.remove();
	tmp2.remove();
}

void MacroEditor::print()
{
 	Path tmp1(::marstmp());

	XMText text(text_);
	text.save(tmp1);

	XMText out(output_);
	out.clear();

	char buf[1024];
	sprintf(buf,"$METVIEW_BIN/beautify -n \"%s\" < \"%s\" | lpr",
		current_->name().c_str(),
		tmp1.str().c_str());


	if(system(buf) == 0)
		progress("Macro printed");
	else
		progress("Print command failed");

	tmp1.remove();
}

void MacroEditor::reset()
{
	XMText out(output_);
	out.clear();

	BaseTextEditor::reset();
	stop();
}

void MacroEditor::check()
{
	start("syntax",false);
}

void MacroEditor::line(const string& s)
{
	int len = s.length();

	// Check for errors
	if( 
		len  > 6    &&
		s[0] == 'L' &&
	    s[1] == 'i' &&
	    s[2] == 'n' &&
	    s[3] == 'e' &&
	    s[4] == ' ')
	{
		int n = 5;
		int m = 0;
		while(n < len && isdigit(s[n]))
		{
			m *= 10;
			m += s[n] - '0';
			n++;
		}
		if(s[n] == ':')
		{
			XMText text(text_);
			text.selectLine(m);
		}
	}
}

void MacroEditor::progress(const string& s)
{
	XMText out(output_);
	out.append(s);

	TabSetCurrent(drawer_,output_,0);

	// Check for errors
	line(s);

}

void MacroEditor::stop()
{
	if(temp_) {
		temp_->destroy();
		temp_ = 0;
	}

	if(task_)
	{
		task_->stop();
		task_ = 0;
	}
}

void MacroEditor::start(const char *action,bool trace)
{
	stop();

	XMText out(output_);
	out.clear();

	XMText text(text_);  
	Path temp(::marstmp());
	text.save(temp);

	// Make object to hold the text.
	temp_ = IconFactory::create(Folder::folder("temporary"),temp.name(),class_);
  
	Action a(action);

	task_ = new MacroRunTask(*this,a,temp_,trace);
	task_->start();

}

void MacroEditor::external()
{
	stop();
	startAlternate();
}

void MacroEditor::modifiedCB(Widget w,XtPointer p)
{
	BaseTextEditor::modifiedCB(w,p);
	stop();
}


static EditorMaker<MacroEditor> editorMaker("MacroEditor");


static EditorButtonMaker<MacroEditor> b1("MacroRun",&MacroEditor::run,1);
static EditorButtonMaker<MacroEditor> b2("MacroTrace",&MacroEditor::trace,2);
static EditorButtonMaker<MacroEditor> b3("MacroRecordOff",&MacroEditor::stop,3);
static EditorButtonMaker<MacroEditor> b4("MacroCheck",&MacroEditor::check,4);

// sep
// MacroRecordOn, MacroRecordOff


static EditorButtonMaker<MacroEditor> b5("MacroEdit",&MacroEditor::external,5);
static EditorButtonMaker<MacroEditor> b6("MacroPrint",&MacroEditor::print,6);
static EditorButtonMaker<MacroEditor> b7("MacroBeau",&MacroEditor::beautify,7);

//static EditorButtonMaker<MacroEditor> b7("MacroEditPref",MacroEditor::externEditor,5);

