/******************************************************************************
 *
 * 9998sketch/global.c
 *
 * (c) Eugene K. Ressler, Jr. 2004, 2005
 *
 * A program related to the book
 *
 * Fundamentals of Virtual World Simulation
 * by Eugene K. Ressler, Jr.
 *
 * No warranty of correctness or capability of any kind is expressed or implied.
 *
 * The author grants free use of this code for any purpose as long any text,
 * executable program, library file, or source code distributed to others 
 * and employing any portion of this code clearly cites the book named above.
 *
 ******************************************************************************/

#include "global.h"

GLOBAL_ENV __the_global_env[1];

// must match GEOL_lang definitions in global.h
char *output_language_str[] = {
	"PSTricks",
	"PGF/TikZ",
};

void init_global_env(GLOBAL_ENV *env)
{
  env->set_p_mask = 0;
  set_ident(env->camera);
  copy_pt_3d(env->bb1, origin_3d);
  copy_pt_3d(env->bb2, origin_3d);
  init_opts(env->opts);
  env->baseline = 0;
  env->output_language = GEOL_PSTRICKS;
}

void set_global_baseline(GLOBAL_ENV *env, FLOAT baseline, SRC_LINE line)
{
  if (baseline == NO_BASELINE)
    return;
  if (global_env_is_set_p(env, GE_BASELINE)) {
    err(line, "baseline is already set");
    return;
  }
  env->set_p_mask |= bit(GE_BASELINE);
  env->baseline = baseline;
}

void set_global_env_extent(GLOBAL_ENV *env, POINT_3D p1, POINT_3D p2, SRC_LINE line)
{
  if (global_env_is_set_p(env, GE_EXTENT)) {
    err(line, "bounding box is already set");
    return;
  }
  env->set_p_mask |= bit(GE_EXTENT);
  copy_pt_3d(env->bb1, p1);
  copy_pt_3d(env->bb2, p2);
}

int get_transformed_global_env_extent(BOX_3D *extent, GLOBAL_ENV *env)
{
  POINT_3D t;
  int i;

  if (!global_env_is_set_p(env, GE_EXTENT))
    return 0;

  init_box_3d(extent);
  if (global_env_is_set_p(env, GE_CAMERA)) {
    for (i = 0; i < 8; i++) {
      t[X] = (i & 1) ? env->bb1[X] : env->bb2[X];
      t[Y] = (i & 2) ? env->bb1[Y] : env->bb2[Y];
      t[Z] = (i & 4) ? env->bb1[Z] : env->bb2[Z];
      transform_pt_3d(t, env->camera, t);
      fold_min_max_pt_3d(extent, t);
    }
  }
  else {
    fold_min_max_pt_3d(extent, env->bb1);
    fold_min_max_pt_3d(extent, env->bb2);
  }
  return 1;
}

void set_global_env_opts(GLOBAL_ENV *env, char *opt_str, SRC_LINE line)
{
  if (global_env_is_set_p(env, GE_OPTS)) {
    err(line, "global options are already set");
    return;
  }
  env->set_p_mask |= bit(GE_OPTS);
  setup_opts(env->opts, opt_str, no_line);
}

void set_global_env_frame(GLOBAL_ENV *env, char *opt_str, SRC_LINE line)
{
  if (global_env_is_set_p(env, GE_FRAME)) {
    err(line, "frame is already set");
    return;
  }
  env->set_p_mask |= bit(GE_FRAME);
  safe_free(env->frame_opts);
  env->frame_opts = opt_str ? safe_strdup(opt_str) : NULL;
}

void set_global_env_camera(GLOBAL_ENV *env, TRANSFORM camera, SRC_LINE line)
{
  if (global_env_is_set_p(env, GE_CAMERA)) {
    err(line, "camera is already set");
    return;
  }
  env->set_p_mask |= bit(GE_CAMERA);
  copy_transform(env->camera, camera);
}

void set_global_output_language(GLOBAL_ENV *env, int output_language, SRC_LINE line)
{
	if (global_env_is_set_p(env, GE_OUTPUT_LANGUAGE)) {
		err(line, "output language is already set");
		return;
	}
	env->set_p_mask |= bit(GE_OUTPUT_LANGUAGE);
	env->output_language = output_language;
}

int get_global_output_language(int *output_language, GLOBAL_ENV *env)
{
	*output_language = env->output_language;
	return global_env_is_set_p(env, GE_OUTPUT_LANGUAGE);
}
