// This module implements the QextScintillaLexerPOV class.
//
// Copyright (c) 2006
// 	Riverbank Computing Limited <info@riverbankcomputing.co.uk>
// 
// This file is part of QScintilla.
// 
// This copy of QScintilla 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 2, or (at your option) any
// later version.
// 
// QScintilla is supplied 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
// QScintilla; see the file LICENSE.  If not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


#include <qcolor.h>
#include <qfont.h>
#include <qsettings.h>

#include "qextscintillalexerpov.h"


// The ctor.
QextScintillaLexerPOV::QextScintillaLexerPOV(QObject *parent,const char *name)
	: QextScintillaLexer(parent,name), fold_comments(FALSE),
	  fold_compact(TRUE), fold_directives(FALSE) 
{
}


// The dtor.
QextScintillaLexerPOV::~QextScintillaLexerPOV()
{
}


// Returns the language name.
const char *QextScintillaLexerPOV::language() const
{
	return "POV";
}


// Returns the lexer name.
const char *QextScintillaLexerPOV::lexer() const
{
	return "pov";
}


// Return the style used for braces.
int QextScintillaLexerPOV::braceStyle() const
{
	return Operator;
}


// Return the string of characters that comprise a word.
const char *QextScintillaLexerPOV::wordCharacters() const
{
	return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_#";
}


// Returns the foreground colour of the text for a style.
QColor QextScintillaLexerPOV::color(int style) const
{
	switch (style)
	{
	case Default:
		return QColor(0xff,0x00,0x80);

	case Comment:
	case CommentLine:
		return QColor(0x00,0x7f,0x00);

	case Number:
		return QColor(0x00,0x7f,0x7f);

	case Operator:
		return QColor(0x00,0x00,0x00);

	case String:
		return QColor(0x7f,0x00,0x7f);

	case Directive:
		return QColor(0x7f,0x7f,0x00);

	case BadDirective:
		return QColor(0x80,0x40,0x20);

	case ObjectsCSGAppearance:
	case TypesModifiersItems:
	case PredefinedIdentifiers:
	case PredefinedFunctions:
	case KeywordSet6:
	case KeywordSet7:
	case KeywordSet8:
		return QColor(0x00,0x00,0x7f);
	}

	return QextScintillaLexer::color(style);
}


// Returns the end-of-line fill for a style.
bool QextScintillaLexerPOV::eolFill(int style) const
{
	return (style == UnclosedString);
}


// Returns the font of the text for a style.
QFont QextScintillaLexerPOV::font(int style) const
{
	QFont f;

	switch (style)
	{
	case Comment:
	case CommentLine:
#if defined(Q_OS_WIN)
		f = QFont("Comic Sans MS",9);
#else
		f = QFont("Bitstream Vera Serif",9);
#endif
		break;

	case UnclosedString:
	case PredefinedIdentifiers:
		f = QextScintillaLexer::font(style);
		f.setBold(TRUE);
		break;

	case BadDirective:
#if defined(Q_OS_WIN)
		f = QFont("Comic Sans MS",9);
#else
		f = QFont("Bitstream Vera Serif",9);
#endif
		f.setItalic(TRUE);
		break;

	default:
		f = QextScintillaLexer::font(style);
	}

	return f;
}


// Returns the set of keywords.
const char *QextScintillaLexerPOV::keywords(int set) const
{
	if (set == 1)
		return
			"declare local include undef fopen fclose read write "
			"default version case range break debug error "
			"warning if ifdef ifndef switch while macro else end";

	if (set == 2)
		return
			"camera light_source light_group object blob sphere "
			"cylinder box cone height_field julia_fractal lathe "
			"prism sphere_sweep superellipsoid sor text torus "
			"bicubic_patch disc mesh mesh2 polygon triangle "
			"smooth_triangle plane poly cubic quartic quadric "
			"isosurface parametric union intersection difference "
			"merge function array spline vertex_vectors "
			"normal_vectors uv_vectors face_indices "
			"normal_indices uv_indices texture texture_list "
			"interior_texture texture_map material_map image_map "
			"color_map colour_map pigment_map normal_map "
			"slope_map bump_map density_map pigment normal "
			"material interior finish reflection irid slope "
			"pigment_pattern image_pattern warp media scattering "
			"density background fog sky_sphere rainbow "
			"global_settings radiosity photons pattern transform "
			"looks_like projected_through contained_by "
			"clipped_by bounded_by";

	if (set == 3)
		return
			"linear_spline quadratic_spline cubic_spline "
			"natural_spline bezier_spline b_spline read write "
			"append inverse open perspective orthographic "
			"fisheye ultra_wide_angle omnimax panoramic "
			"spherical spotlight jitter circular orient "
			"media_attenuation media_interaction shadowless "
			"parallel refraction collect pass_through "
			"global_lights hierarchy sturm smooth gif tga iff "
			"pot png pgm ppm jpeg tiff sys ttf quaternion "
			"hypercomplex linear_sweep conic_sweep type "
			"all_intersections split_union cutaway_textures "
			"no_shadow no_image no_reflection double_illuminate "
			"hollow uv_mapping all use_index use_color "
			"use_colour no_bump_scale conserve_energy fresnel "
			"average agate boxed bozo bumps cells crackle "
			"cylindrical density_file dents facets granite "
			"leopard marble onion planar quilted radial ripples "
			"spotted waves wood wrinkles solid use_alpha "
			"interpolate magnet noise_generator toroidal "
			"ramp_wave triangle_wave sine_wave scallop_wave "
			"cubic_wave poly_wave once map_type method fog_type "
			"hf_gray_16 charset ascii utf8 rotate scale "
			"translate matrix location right up direction sky "
			"angle look_at aperture blur_samples focal_point "
			"confidence variance radius falloff tightness "
			"point_at area_light adaptive fade_distance "
			"fade_power threshold strength water_level tolerance "
			"max_iteration precision slice u_steps v_steps "
			"flatness inside_vector accuracy max_gradient "
			"evaluate max_trace precompute target ior dispersion "
			"dispersion_samples caustics color colour rgb rgbf "
			"rgbt rgbft red green blue filter transmit gray hf "
			"fade_color fade_colour quick_color quick_colour "
			"brick checker hexagon brick_size mortar bump_size "
			"ambient diffuse brilliance crand phong phong_size "
			"metallic specular roughness reflection_exponent "
			"exponent thickness gradient spiral1 spiral2 "
			"agate_turb form metric offset df3 coords size "
			"mandel exterior julia control0 control1 altitude "
			"turbulence octaves omega lambda repeat flip "
			"black-hole orientation dist_exp major_radius "
			"frequency phase intervals samples ratio absorption "
			"emission aa_threshold aa_level eccentricity "
			"extinction distance turb_depth fog_offset fog_alt "
			"width arc_angle falloff_angle adc_bailout "
			"ambient_light assumed_gamma irid_wavelength "
			"number_of_waves always_sample brigthness count "
			"error_bound gray_threshold load_file "
			"low_error_factor max_sample minimum_reuse "
			"nearest_count pretrace_end pretrace_start "
			"recursion_limit save_file spacing gather "
			"max_trace_level autostop expand_thresholds";

	if (set == 4)
		return
			"x y z t u v yes no true false on off clock "
			"clock_delta clock_on final_clock final_frame "
			"frame_number image_height image_width initial_clock "
			"initial_frame pi version";

	if (set == 5)
		return
			"abs acos acosh asc asin asinh atan atanh atan2 ceil "
			"cos cosh defined degrees dimensions dimension_size "
			"div exp file_exists floor inside int ln log max min "
			"mod pow prod radians rand seed select sin sinh sqrt "
			"strcmp strlen sum tan tanh val vdot vlength "
			"min_extent max_extent trace vaxis_rotate vcross "
			"vrotate vnormalize vturbulence chr concat str "
			"strlwr strupr substr vstr sqr cube reciprocal pwr";

	return 0;
}


// Returns the user name of a style.
QString QextScintillaLexerPOV::description(int style) const
{
	switch (style)
	{
	case Default:
		return tr("Default");

	case Comment:
		return tr("Comment");

	case CommentLine:
		return tr("Comment line");

	case Number:
		return tr("Number");

	case Operator:
		return tr("Operator");

	case Identifier:
		return tr("Identifier");

	case String:
		return tr("String");

	case UnclosedString:
		return tr("Unclosed string");

	case Directive:
		return tr("Directive");

	case BadDirective:
		return tr("Bad directive");

	case ObjectsCSGAppearance:
		return tr("Objects, CSG and appearance");

	case TypesModifiersItems:
		return tr("Types, modifiers and items");

	case PredefinedIdentifiers:
		return tr("Predefined identifiers");

	case PredefinedFunctions:
		return tr("Predefined functions");

	case KeywordSet6:
		return tr("User defined 1");

	case KeywordSet7:
		return tr("User defined 2");

	case KeywordSet8:
		return tr("User defined 3");
	}

	return QString::null;
}


// Returns the background colour of the text for a style.
QColor QextScintillaLexerPOV::paper(int style) const
{
	switch (style)
	{
	case UnclosedString:
		return QColor(0xe0,0xc0,0xe0);

	case ObjectsCSGAppearance:
		return QColor(0xff,0xd0,0xd0);

	case TypesModifiersItems:
		return QColor(0xff,0xff,0xd0);

	case PredefinedFunctions:
		return QColor(0xd0,0xd0,0xff);

	case KeywordSet6:
		return QColor(0xd0,0xff,0xd0);

	case KeywordSet7:
		return QColor(0xd0,0xd0,0xd0);

	case KeywordSet8:
		return QColor(0xe0,0xe0,0xe0);
	}

	return QextScintillaLexer::paper(style);
}


// Refresh all properties.
void QextScintillaLexerPOV::refreshProperties()
{
	setCommentProp();
	setCompactProp();
	setDirectiveProp();
}


// Read properties from the settings.
bool QextScintillaLexerPOV::readProperties(QSettings &qs,const QString &prefix)
{
	int rc = TRUE;
	bool ok, flag;

	// Read the fold comments flag.
	flag = qs.readBoolEntry(prefix + "foldcomments",FALSE,&ok);

	if (ok)
		fold_comments = flag;
	else
		rc = FALSE;

	// Read the fold compact flag.
	flag = qs.readBoolEntry(prefix + "foldcompact",TRUE,&ok);

	if (ok)
		fold_compact = flag;
	else
		rc = FALSE;

	// Read the fold directives flag.
	flag = qs.readBoolEntry(prefix + "folddirectives",FALSE,&ok);

	if (ok)
		fold_directives = flag;
	else
		rc = FALSE;

	return rc;
}


// Write properties to the settings.
bool QextScintillaLexerPOV::writeProperties(QSettings &qs,const QString &prefix) const
{
	int rc = TRUE;

	// Write the fold comments flag.
	if (!qs.writeEntry(prefix + "foldcomments",fold_comments))
		rc = FALSE;

	// Write the fold compact flag.
	if (!qs.writeEntry(prefix + "foldcompact",fold_compact))
		rc = FALSE;

	// Write the fold directives flag.
	if (!qs.writeEntry(prefix + "folddirectives",fold_directives))
		rc = FALSE;

	return rc;
}


// Return TRUE if comments can be folded.
bool QextScintillaLexerPOV::foldComments() const
{
	return fold_comments;
}


// Set if comments can be folded.
void QextScintillaLexerPOV::setFoldComments(bool fold)
{
	fold_comments = fold;

	setCommentProp();
}


// Set the "fold.comment" property.
void QextScintillaLexerPOV::setCommentProp()
{
	emit propertyChanged("fold.comment",(fold_comments ? "1" : "0"));
}


// Return TRUE if folds are compact.
bool QextScintillaLexerPOV::foldCompact() const
{
	return fold_compact;
}


// Set if folds are compact
void QextScintillaLexerPOV::setFoldCompact(bool fold)
{
	fold_compact = fold;

	setCompactProp();
}


// Set the "fold.compact" property.
void QextScintillaLexerPOV::setCompactProp()
{
	emit propertyChanged("fold.compact",(fold_compact ? "1" : "0"));
}


// Return TRUE if directives can be folded.
bool QextScintillaLexerPOV::foldDirectives() const
{
	return fold_directives;
}


// Set if directives can be folded.
void QextScintillaLexerPOV::setFoldDirectives(bool fold)
{
	fold_directives = fold;

	setDirectiveProp();
}


// Set the "fold.directive" property.
void QextScintillaLexerPOV::setDirectiveProp()
{
	emit propertyChanged("fold.directive",(fold_directives ? "1" : "0"));
}
