#include <Python.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <X11/extensions/Xrandr.h>


int gargc;
char **gargv;
SizeID curSize;
XRRScreenConfiguration *screenConf;
XRRScreenSize *sizes;
Rotation rots, curRot;
bool available = false;
short *rates;
int numRes=0, numRate=0;


/* It is *very* important to check with this function before attempting any RandR functions. 
 * Most will SEGFAULT if the X Server doesn't have RandR support */
static PyObject *pyrandr_randrAvailable(PyObject *self, PyObject *args) {

	return Py_BuildValue("b", available);

}

static PyObject *pyrandr_getCurRes(PyObject *self, PyObject *args) {

	return Py_BuildValue("i", curSize);

}


static PyObject *pyrandr_getNumRes(PyObject *self, PyObject *args) {

	return Py_BuildValue("i", numRes);

}


static PyObject *pyrandr_getRes(PyObject *self, PyObject *args) {

	int res;

	if(!PyArg_ParseTuple(args, "i", &res))
		return 0;
	

	return Py_BuildValue("(ii)", sizes[res].width, sizes[res].height);
	
}


static PyObject *pyrandr_getCurRot(PyObject *self, PyObject *args) {

	return Py_BuildValue("i", curRot);

}


static PyObject *pyrandr_getNumRot(PyObject *self, PyObject *args) {

	int rot;

	if(!PyArg_ParseTuple(args, "i", &rot))
		return 0;
	
	return Py_BuildValue("i", 0);

}



static PyObject *pyrandr_getCurRate(PyObject *self, PyObject *args) {

	return Py_BuildValue("i", curRot - 1);

}


static PyObject *pyrandr_getNumRates(PyObject *self, PyObject *args) {

	int res;
	
	if(!PyArg_ParseTuple(args, "i", &res))
		return 0;

	rates = XRRConfigRates (screenConf, res, &numRate);
	
	return Py_BuildValue("i", numRate);

}


static PyObject *pyrandr_getRate(PyObject *self, PyObject *args) {

	int rate, res;

	if(!PyArg_ParseTuple(args, "i", &res, &rate))
		return 0;

	rates = XRRConfigRates (screenConf, res, &numRate);

	return Py_BuildValue("i", rates[rate]);

}


static PyObject *pyrandr_setRes(PyObject *self, PyObject *args) {

	int setResolution;
	int setRate;
	
	if(!PyArg_ParseTuple(args, "ii", &setResolution, &setRate))
		return 0;
	
	Status status = RRSetConfigFailed;
	status = XRRSetScreenConfigAndRate (GDK_DISPLAY(), screenConf, GDK_ROOT_WINDOW(), setResolution, curRot, setRate, CurrentTime);
	screenConf = XRRGetScreenInfo (GDK_DISPLAY(), GDK_ROOT_WINDOW());
	curSize = XRRConfigCurrentConfiguration (screenConf, &curRot);
	rates = XRRConfigRates (screenConf, curSize, &numRate);

	Py_INCREF(Py_None);
	return Py_None;

}


//Method table
static PyMethodDef RandRMethods[] = {
	
	{"randrAvailable", pyrandr_randrAvailable, METH_VARARGS, "Checks to see if the RandR extension is available **VERY IMPORTANT TO CHECK**"},
	{"getCurRes", pyrandr_getCurRes, METH_VARARGS, "Return the current resolution's number"},
	{"getNumRes", pyrandr_getNumRes, METH_VARARGS, "Return the number of resolutions"},
	{"getRes", pyrandr_getRes, METH_VARARGS, "Return a resolution corresponding to a number"},
	{"getCurRot", pyrandr_getCurRot, METH_VARARGS, "Return the current rotation's number"},
	{"getNumRot", pyrandr_getNumRot, METH_VARARGS, "Return available rotations"},
	{"getNumRates", pyrandr_getNumRates, METH_VARARGS, "Return the number of refresh rates available at the specified resolution"},
	{"getCurRate", pyrandr_getCurRate, METH_VARARGS, "Return the current refresh rate"},
	{"getRate", pyrandr_getRate, METH_VARARGS, "Return the rate corresponding to a number"},
	{"setRes", pyrandr_setRes, METH_VARARGS, "Set the screen resolution"},
	{NULL, NULL, 0, NULL}
	
};
 

PyMODINIT_FUNC initpyrandr(void) {

	        (void) Py_InitModule("pyrandr", RandRMethods);

		gtk_init(&gargc, &gargv);

		/* Check we have RandR */
		int event, err;
		available = XRRQueryExtension(GDK_DISPLAY(), &event, &err);
		if(available) {
		
			screenConf = XRRGetScreenInfo (GDK_DISPLAY(), GDK_ROOT_WINDOW());
			curSize = XRRConfigCurrentConfiguration (screenConf, &curRot);
			sizes = XRRConfigSizes(screenConf, &numRes);
			rots = XRRConfigRotations(screenConf, &curRot);

		}

}



int main(int argc, char **argv) {

	Py_SetProgramName(argv[0]);
	Py_Initialize();
	initpyrandr();

	return 0;
}


