#ifndef H_CORAL_DIFF_MYERSPATCH
#define H_CORAL_DIFF_MYERSPATCH
// This file is part of the Coral project.
// Please read the copyright notice in the LICENSE file.

#include "MyersDiff.h"

namespace coral { namespace DIFF {

template <class T>
void swap(T& v1, T& v2) {
	T _tmp = v1;
	v1 = v2;
	v2 = _tmp;
}

template <class Type>
void MyersDefaultPatch(std::vector<Type>& result,
		       typename answer<Type>::command_t cmd,
		       int idx,
		       Type value) {
	typename std::vector<Type>::iterator i = result.begin();
	std::advance(i, idx);
	if (cmd == answer<Type>::DELETE) {
		result.erase(i); // slow
	} else {
		coral_assert(cmd == answer<Type>::INSERT);
		result.insert(i, value); // slow
	}
}

template <class Type>
void
MyersPatch(const std::deque<answer<Type> >& diff,
	   std::vector<Type>& result,
	   bool reverse = false,
	   void (*updateFunc)(std::vector<Type>& result,
			      typename answer<Type>::command_t cmd,
			      int idx,
			      Type value) = MyersDefaultPatch<Type>
	   ) {
	typename answer<Type>::command_t ins = answer<Type>::INSERT;
	typename answer<Type>::command_t del = answer<Type>::DELETE;
	int start = 0;
	int end = diff.size();
	int delta = 1;

	if (reverse) {
		swap(ins, del);
		start = end - 1;
		end = -1;
		delta = -1;
	}
	coral_assert(ins != del);

	for (int i = start; i != end; i += delta) {
		const answer<Type>& part = diff[i];
		typename answer<Type>::command_t cmd;
		if (part.cmd == ins) {
			cmd = answer<Type>::INSERT;
		} else {
			coral_assert(part.cmd == del);
			cmd = answer<Type>::DELETE;
		}
		(*updateFunc)(result, cmd, part.idx, part.t);
	}
}
	     
} }


#endif
