/*
 * EasyChem
 * A program for creating and editing molecular formulas.
 *
 * Copyright (C) 2003, 2004, 2005 François-Xavier Coudert
 * 
 * Distributed under the General Public Licence (GPL).
 * See file COPYING in the source distribution for more details.
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <gtk/gtk.h>

#include "common.h"
#include "auxi.h"


long int
precise_time (void)
{
  GTimeVal t;

  g_get_current_time (&t);
  return 1000 * t.tv_sec + t.tv_usec / 1000;
}


void
info_arc (LLINT * xc, LLINT * yc, int *theta1, int *theta2, int *dir,
	  double x1, double y1, double x2, double y2, double x3, double y3)
{
  double denom, x, y, t1, t2, t3;

  denom = x1 * (y3 - y2) + x2 * (y1 - y3) + x3 * (y2 - y1);
  x = 0.5 * ((SQR (x1) + SQR (y1)) * (y3 - y2)
	     + (SQR (x2) + SQR (y2)) * (y1 - y3)
	     + (SQR (x3) + SQR (y3)) * (y2 - y1)) / denom;
  y = -0.5 * ((SQR (x1) + SQR (y1)) * (x3 - x2)
	      + (SQR (x2) + SQR (y2)) * (x1 - x3)
	      + (SQR (x3) + SQR (y3)) * (x2 - x1)) / denom;

  *xc = (LLINT) x;
  *yc = (LLINT) y;

  t1 = ATAN2 (y - y1, x1 - x);
  t2 = ATAN2 (y - y2, x2 - x) - t1;
  t3 = ATAN2 (y - y3, x3 - x) - t1;
  while (t2 < 0)
    t2 += 2 * G_PI;
  while (t3 < 0)
    t3 += 2 * G_PI;

  if (dir != NULL)
    *dir = 1;

  if (t3 > t2)
    {
      t2 -= 2 * G_PI;
      if (dir != NULL)
	*dir = -1;
    }

  if (theta1 != NULL)
    *theta1 = (int) (t1 * 180 * 64 / G_PI);
  if (theta2 != NULL)
    *theta2 = (int) (t2 * 180 * 64 / G_PI);
}


void
info_arc_export (double *xc, double *yc, double *theta1, double *theta2,
		 int *dir, double x1, double y1, double x2, double y2,
		 double x3, double y3)
{
  double denom, x, y, t1, t2, t3;

  denom = x1 * (y3 - y2) + x2 * (y1 - y3) + x3 * (y2 - y1);
  x = 0.5 * ((SQR (x1) + SQR (y1)) * (y3 - y2)
	     + (SQR (x2) + SQR (y2)) * (y1 - y3)
	     + (SQR (x3) + SQR (y3)) * (y2 - y1)) / denom;
  y = -0.5 * ((SQR (x1) + SQR (y1)) * (x3 - x2)
	      + (SQR (x2) + SQR (y2)) * (x1 - x3)
	      + (SQR (x3) + SQR (y3)) * (x2 - x1)) / denom;

  *xc = x;
  *yc = y;

  t1 = ATAN2 (y - y1, x1 - x);
  t2 = ATAN2 (y - y2, x2 - x) - t1;
  t3 = ATAN2 (y - y3, x3 - x) - t1;
  while (t2 < 0)
    t2 += 2 * G_PI;
  while (t3 < 0)
    t3 += 2 * G_PI;

  if (dir != NULL)
    *dir = 1;

  if (t3 > t2)
    {
      t2 -= 2 * G_PI;
      if (dir != NULL)
	*dir = -1;
    }

  if (theta1 != NULL)
    *theta1 = (t1 * 180 / G_PI);
  if (theta2 != NULL)
    *theta2 = (t2 * 180 / G_PI);
}


double
dist2_to_arc (struct Bond *ref, const LLINT x, const LLINT y)
{
  double denom, cx, cy, t1, t2, t3;

  denom = ref->x1 * (ref->y3 - ref->y2)
    + ref->x2 * (ref->y1 - ref->y3) + ref->x3 * (ref->y2 - ref->y1);
  cx = 0.5 * ((SQR (ref->x1)
	       + SQR (ref->y1)) * (ref->y3 - ref->y2)
	      + (SQR (ref->x2)
		 + SQR (ref->y2)) * (ref->y1 - ref->y3)
	      + (SQR (ref->x3)
		 + SQR (ref->y3)) * (ref->y2 - ref->y1)) / denom;
  cy = -0.5 * ((SQR (ref->x1)
		+ SQR (ref->y1)) * (ref->x3 - ref->x2)
	       + (SQR (ref->x2)
		  + SQR (ref->y2)) * (ref->x1 - ref->x3)
	       + (SQR (ref->x3)
		  + SQR (ref->y3)) * (ref->x2 - ref->x1)) / denom;

  t1 = ATAN2 (cy - ref->y1, ref->x1 - cx);
  t2 = ATAN2 (cy - ref->y2, ref->x2 - cx) - t1;
  t3 = ATAN2 (cy - ref->y3, ref->x3 - cx) - t1;
  while (t2 < 0)
    t2 += 2 * G_PI;
  while (t3 < 0)
    t3 += 2 * G_PI;
  if (t3 > t2)
    t2 -= 2 * G_PI;

  t3 = ATAN2 (cy - y, x - cx) - t1;
  while (t3 < 0)
    t3 += 2 * G_PI;
  if (t2 < 0)
    t3 -= 2 * G_PI;

  if ((t2 > 0 || t3 < t2) && (t2 < 0 || t3 > t2))
    return VERY_BIG;
  else
    return SQR (hypot (cx - x, cy - y) - hypot (cx - ref->x1, cy - ref->y1));
}


/* Open a config file for reading or writing (NULL on failure)
 *   - write is 0 if file is to be opened for reading
 *              1 if file is to be opened for writing
 */
     
FILE *
open_config_file (const int write)
{
  FILE *file;
  gchar *f;

/* First, we try $HOME/.easychemrc */
  f = g_strconcat (g_get_home_dir (), G_DIR_SEPARATOR_S, ".easychemrc", NULL);
  file = fopen (f, write == FALSE ? "r" : "w");
  g_free (f);
  if (file != NULL)
    return file;

#if 0
/* Then, we have /tmp/$USERNAME.easychemrc */
  f = g_strconcat (g_get_tmp_dir (), G_DIR_SEPARATOR_S,
                   g_get_user_name (), ".easychemrc", NULL);
  file = fopen (f, write == FALSE ? "r" : "w");
  g_free (f);
  if (file != NULL)
    return file;
#endif

/* Nothing worked */
  return NULL;
}


/* Save EasyChem configuration to a config file (.easychemrc) */
int
write_config_file (void)
{
  FILE *file;

  file = open_config_file (TRUE);
  if (file == NULL)
    return 0;

  fprintf (file, "global_height=%" LLFORMAT "\n", prop.global_height);
  fprintf (file, "global_width=%" LLFORMAT "\n", prop.global_width);
  fprintf (file, "latex_export=%d\n", prop.latex_export);
  if (prop.path_gs != NULL)
    fprintf (file, "path_gs=%s\n", prop.path_gs);
  if (prop.path_pstoedit != NULL)
    fprintf (file, "path_pstoedit=%s\n", prop.path_pstoedit);

  fclose (file);
  return 1;
}


/* Read the configuration file for easychem */
int
read_config_file (void)
{
#define LEN 100
  FILE *file;
  char buf[LEN], *c;

  file = open_config_file (FALSE);
  if (file == NULL)
    return 0;

  while (fgets (buf, LEN, file) != NULL)
  {
    if (strncmp (buf, "global_height=", 14) == 0)
      sscanf (buf, "global_height=%" LLFORMAT "\n", &(prop.global_height));
    if (strncmp (buf, "global_width=", 13) == 0)
      sscanf (buf, "global_width=%" LLFORMAT "\n", &(prop.global_width));
    if (strncmp (buf, "latex_export=", 13) == 0)
      sscanf (buf, "latex_export=%d\n", &(prop.latex_export));
    if (strncmp (buf, "path_gs=", 8) == 0)
    {
      /* We have to remove the newline at the end */
      c = buf + 8;
      while (*c != '\n')
	c++;
      *c = '\0';

      prop.path_gs = g_strdup (buf + 8);
    }
    if (strncmp (buf, "path_pstoedit=", 14) == 0)
    {
      /* We have to remove the newline at the end */
      c = buf + 14;
      while (*c != '\n')
	c++;
      *c = '\0';

      prop.path_pstoedit = g_strdup (buf + 14);
    }
  }

  fclose (file);
  return 1;
#undef LEN
}

