#include <common.h>
#include <fb.h>
#include <errno.h>
#include <command.h>
#include <getopt.h>
#include <fcntl.h>
#include <fs.h>
#include <init.h>

static int fb_ioctl(struct cdev* cdev, int req, void *data)
{
	struct fb_info *info = cdev->priv;

	switch (req) {
	case FBIOGET_SCREENINFO:
		memcpy(data, info, sizeof(*info));
		break;
	case FBIO_ENABLE:
		info->fbops->fb_enable(info);
		break;
	case FBIO_DISABLE:
		info->fbops->fb_disable(info);
		break;
	default:
		return -ENOSYS;
	}

	return 0;
}

static int fb_enable_set(struct device_d *dev, struct param_d *param,
		const char *val)
{
	struct fb_info *info = dev->priv;
	int enable;
	char *new;

	if (!val)
		return dev_param_set_generic(dev, param, NULL);

	enable = simple_strtoul(val, NULL, 0);

	if (enable) {
		if (!info->enabled)
			info->fbops->fb_enable(info);
		new = "1";
	} else {
		if (info->enabled)
			info->fbops->fb_disable(info);
		new = "0";
	}

	dev_param_set_generic(dev, param, new);

	info->enabled = !!enable;

	return 0;
}

static int fb_setup_mode(struct device_d *dev, struct param_d *param,
		const char *val)
{
	struct fb_info *info = dev->priv;
	int mode, ret;

	if (info->enabled != 0)
		return -EPERM;

	if (!val)
		return dev_param_set_generic(dev, param, NULL);

	for (mode = 0; mode < info->num_modes; mode++) {
		if (!strcmp(info->mode_list[mode].name, val))
			break;
	}
	if (mode >= info->num_modes)
		return -EINVAL;

	info->mode = &info->mode_list[mode];

	info->xres = info->mode->xres;
	info->yres = info->mode->yres;

	ret = info->fbops->fb_activate_var(info);

	if (!ret) {
		dev->map_base = (unsigned long)info->screen_base;
		info->cdev.size = info->xres * info->yres * (info->bits_per_pixel >> 3);
		dev->size = info->cdev.size;
		dev_param_set_generic(dev, param, val);
	} else
		info->cdev.size = 0;

	return ret;
}

static struct file_operations fb_ops = {
	.read	= mem_read,
	.write	= mem_write,
	.memmap	= generic_memmap_rw,
	.lseek	= dev_lseek_default,
	.ioctl	= fb_ioctl,
};

int register_framebuffer(struct fb_info *info)
{
	int id = get_free_deviceid("fb");
	struct device_d *dev;

	info->cdev.ops = &fb_ops;
	info->cdev.name = asprintf("fb%d", id);
	info->cdev.size = info->xres * info->yres * (info->bits_per_pixel >> 3);
	info->cdev.dev = &info->dev;
	info->cdev.priv = info;
	info->cdev.dev->map_base = (unsigned long)info->screen_base;
	info->cdev.dev->size = info->cdev.size;

	dev = &info->dev;
	dev->priv = info;
	dev->id = id;

	sprintf(dev->name, "fb");

	register_device(&info->dev);
	dev_add_param(dev, "enable", fb_enable_set, NULL, 0);
	dev_set_param(dev, "enable", "0");

	if (info->num_modes && (info->mode_list != NULL) &&
			(info->fbops->fb_activate_var != NULL)) {
		dev_add_param(dev, "mode_name", fb_setup_mode, NULL, 0);
		dev_set_param(dev, "mode_name", info->mode_list[0].name);
	}

	devfs_create(&info->cdev);

	return 0;
}

static void fb_info(struct device_d *dev)
{
	struct fb_info *info = dev->priv;
	int i;

	if (!info->num_modes)
		return;

	printf("available modes:\n");

	for (i = 0; i < info->num_modes; i++) {
		struct fb_videomode *mode = &info->mode_list[i];

		printf("%-10s %dx%d@%d\n", mode->name,
				mode->xres, mode->yres, mode->refresh);
	}

	printf("\n");
}

static int fb_probe(struct device_d *hw_dev)
{
	return 0;
}

static struct driver_d fb_driver = {
	.name  = "fb",
	.probe = fb_probe,
	.info = fb_info,
};

static int fb_init_driver(void)
{
	register_driver(&fb_driver);
	return 0;
}
device_initcall(fb_init_driver);
