// Copyright (c) 2007 Omer Rauchwerger (a.k.a rauchy) (omer@rauchy.net)
// All rights reserved.
//
// This file is part of Regionerate.
//
// This program 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 of the License,
// or (at your option) any later version.
//
// This program 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 this program. If not, see .
using System;
using System.Text;
using Rauchy.Regionerate.Domain.Entities;
namespace Rauchy.Regionerate.Shared.Components.Rendering
{
///
/// Renders objects into strings.
///
public abstract class RegionRenderer : ICodeRenderer
{
#region Fields (2)
private readonly CodeLayout.Configuration _configuration;
private const string TabAmountCannotBeLessThanZero = "Tab amount cannot be less than zero";
#endregion Fields
#region Constructors (1)
protected RegionRenderer( CodeLayout.Configuration configuration )
{
if ( configuration.RenderingOptions.TabAmount < 0 )
{
throw new ArgumentOutOfRangeException( TabAmountCannotBeLessThanZero );
}
_configuration = configuration;
}
#endregion Constructors
#region Properties (1)
protected CodeLayout.Configuration Configuration
{
get
{
return _configuration;
}
}
#endregion Properties
#region Methods (6)
// Public Methods (2)
// [rgn] Public Methods (2)
public static RegionRenderer CreateNew( RegionStyle style, CodeLayout.Configuration configuration )
{
switch ( style )
{
case RegionStyle.Visible:
return new VisibleRegionRenderer( configuration );
case RegionStyle.Comment:
return new CommentRegionRenderer( configuration );
case RegionStyle.Invisible:
return new InvisibleRegionRenderer( configuration );
default:
throw new NotSupportedException();
}
}
///
/// Creates a string representation for the provided .
///
///
/// Thrown when region is null.
///
public virtual string Render( Region region )
{
if ( region == null )
{
throw new ArgumentNullException( "region" );
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append( RenderHeader( region ) );
// Pad first child.
if ( region.Children.Count > 0 )
{
for ( int i = 0; i < region.PadFirstChild; i++ )
{
stringBuilder.AppendLine();
}
}
// Append children
foreach ( Code child in region.Children )
{
string childText = RenderingCentral.Render( child, _configuration );
stringBuilder.Append( childText );
}
// Pad last child.
if ( region.Children.Count > 0 )
{
for ( int i = 0; i < region.PadLastChild; i++ )
{
stringBuilder.AppendLine();
}
}
stringBuilder.Append( RenderFooter( region ) );
return stringBuilder.ToString();
}
// Protected Methods (3)
// [rgn] Protected Methods (3)
///
/// Build the footer portion which is shared to all rendering styles.
/// Consists the symbol and region title.
///
///
///
protected virtual string RenderFooter( Region region )
{
return _configuration.Symbol.Embed( region.Title );
}
///
/// Build the header portion which is shared to all rendering styles.
/// Consists of the symbol, region title and children count. (if required)
///
///
///
protected virtual string RenderHeader( Region region )
{
string text = region.Title;
if ( _configuration.RenderingOptions.ShowCount )
{
text += string.Format( " ({0})", CountRecognizedCode( region ) );
}
return _configuration.Symbol.Embed( text );
}
protected string RenderHeader( Region region, string prefix, string title )
{
StringBuilder header = new StringBuilder();
header.Append( TextUtilities.GetTabString( _configuration.RenderingOptions ) );
// Tabifies the region header.
header.Append( prefix );
header.Append( title );
header.AppendLine();
return header.ToString();
}
// Private Methods (1)
// [rgn] Private Methods (1)
///
/// Counts the functional code instances inside a . (recursive)
///
/// The region to count.
///
/// The amount of objects inside the and
/// its inner instances.
///
private static int CountRecognizedCode( Region region )
{
int count = 0;
foreach ( Code code in region.Children )
{
if ( code is FunctionalCode )
{
count++;
}
if ( code is Region )
{
count += CountRecognizedCode( code as Region );
}
}
return count;
}
#endregion Methods
}
}