/*******************************************************************
 * File:     screen.c
 * Purpose:  Simple screen handling class for JavaScript
 * Author:   Justin Fletcher
 * Date:     17 May 1999
 ******************************************************************/

#include "jsapi.h"
#include "swis.h"

static JSClass screen_class;

enum screen_tinyid {
    SCREEN_WIDTH	    = -1,
    SCREEN_HEIGHT   	    = -2,
    SCREEN_PIXEL_DEPTH	    = -3,
    SCREEN_COLOR_DEPTH	    = -4,
    SCREEN_AVAIL_WIDTH	    = -5,
    SCREEN_AVAIL_HEIGHT	    = -6,
    SCREEN_AVAIL_LEFT	    = -7,
    SCREEN_AVAIL_TOP	    = -8
};

static JSPropertySpec screen_props[] = {
    {"width",		SCREEN_WIDTH,		JSPROP_ENUMERATE | JSPROP_READONLY},
    {"height",		SCREEN_HEIGHT,		JSPROP_ENUMERATE | JSPROP_READONLY},
    {"pixelDepth",      SCREEN_PIXEL_DEPTH,     JSPROP_ENUMERATE | JSPROP_READONLY},
    {"colorDepth",      SCREEN_COLOR_DEPTH,     JSPROP_ENUMERATE | JSPROP_READONLY},
    {"availWidth",      SCREEN_AVAIL_WIDTH,     JSPROP_ENUMERATE | JSPROP_READONLY},
    {"availHeight",     SCREEN_AVAIL_HEIGHT,    JSPROP_ENUMERATE | JSPROP_READONLY},
    {"availLeft",       SCREEN_AVAIL_LEFT,      JSPROP_ENUMERATE | JSPROP_READONLY},
    {"availTop",        SCREEN_AVAIL_TOP,       JSPROP_ENUMERATE | JSPROP_READONLY},
    {0}
};

PR_STATIC_CALLBACK(JSBool)
screen_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
    jsint slot;

    if (!JSVAL_IS_INT(id))
	return JS_TRUE;

    slot = JSVAL_TO_INT(id);

    switch (slot) {
	case SCREEN_WIDTH:
            {
              int eigen,size;
              _swix(OS_ReadModeVariable,_INR(0,1)|_OUT(2),-1,4,&eigen);
              _swix(OS_ReadModeVariable,_INR(0,1)|_OUT(2),-1,11,&size);
              *vp = INT_TO_JSVAL((size+1)<<eigen);
            }
	    break;
	case SCREEN_HEIGHT:
            {
              int eigen,size;
              _swix(OS_ReadModeVariable,_INR(0,1)|_OUT(2),-1,5,&eigen);
              _swix(OS_ReadModeVariable,_INR(0,1)|_OUT(2),-1,12,&size);
              *vp = INT_TO_JSVAL((size+1)<<eigen);
            }
	    break;
	case SCREEN_PIXEL_DEPTH: /* number of bits per pixel */
            {
              int depth;
              _swix(OS_ReadModeVariable,_INR(0,1)|_OUT(2),-1,9,&depth);
              *vp = INT_TO_JSVAL(depth);
            }
	    break;
	case SCREEN_COLOR_DEPTH:
            {
              int colours;
              _swix(OS_ReadModeVariable,_INR(0,1)|_OUT(2),-1,3,&colours);
              if (colours==-1)
                colours=1<<24;
              else
                colours+=1;
              *vp = INT_TO_JSVAL(colours);
            }
	    break;
	case SCREEN_AVAIL_WIDTH:
            {
              int eigen,size;
              _swix(OS_ReadModeVariable,_INR(0,1)|_OUT(2),-1,4,&eigen);
              _swix(OS_ReadModeVariable,_INR(0,1)|_OUT(2),-1,11,&size);
              *vp = INT_TO_JSVAL(size<<eigen);
            }
	    break;
	case SCREEN_AVAIL_HEIGHT:
            {
              int eigen,size;
              _swix(OS_ReadModeVariable,_INR(0,1)|_OUT(2),-1,5,&eigen);
              _swix(OS_ReadModeVariable,_INR(0,1)|_OUT(2),-1,12,&size);
              *vp = INT_TO_JSVAL(size<<eigen);
            }
	    break;
	case SCREEN_AVAIL_LEFT:
            *vp = INT_TO_JSVAL(0);
	    break;
	case SCREEN_AVAIL_TOP:
            *vp = INT_TO_JSVAL(0);
	    break;
	default:
	    return JS_TRUE;
    }
    return JS_TRUE;
}


PR_STATIC_CALLBACK(void)
screen_finalize(JSContext *cx, JSObject *obj)
{
  /* Don't need to do anything */
}

static JSClass screen_class = {
    "Screen", 0,
    JS_PropertyStub, JS_PropertyStub, screen_getProperty, screen_getProperty,
    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, screen_finalize
};

PR_STATIC_CALLBACK(JSBool)
Screen(JSContext *cx, JSObject *obj,
          uint argc, jsval *argv, jsval *rval)
{
    return JS_TRUE;
}

JSObject *RO_Init_screen(JSContext *cx,JSObject *initobj)
{
  JSObject *obj;
  obj = JS_InitClass(cx, initobj, NULL, &screen_class,
                     Screen, 0, screen_props, NULL, NULL, NULL);
  return obj;
}
