/* global.c
   Copyright (C) 2005,2006,2007 Eugene K. Ressler, Jr.

This file is part of Sketch, a small, simple system for making 
3d drawings with LaTeX and the PSTricks or TikZ package.

Sketch is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

Sketch is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Sketch; see the file COPYING.txt.  If not, see
http://www.gnu.org/copyleft */

#include "global.h"

GLOBAL_ENV __the_global_env[1];

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

void
init_global_env (GLOBAL_ENV * env, PST_VERSION *pst_version)
{
  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 | GEOL_LATEX;
  *env->pst_version = *pst_version;
}

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);
}

int cmp_with_global_pst_version(GLOBAL_ENV * env,
				char * version_str, 
				SRC_LINE line)
{
  PST_VERSION v[1];

  parse_pst_version(v, version_str, line);
  return pst_version_cmp(env->pst_version, v);
}

