///
/// Copyright © 2003-2008 JetBrains s.r.o.
/// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder).
///
using System;
using System.Collections;
using System.Text;
using JetBrains.Omea.Base;
namespace JetBrains.Omea.ResourceStore
{
///
/// The mask for calculating the display name of a resource.
///
internal class DisplayNameMask
{
// TODO: optimize (perform complete parsing when the mask is first constructed)
private string _mask;
private string[] _alternatives;
private BitArray _properties;
public DisplayNameMask( string mask, bool validate )
{
_mask = mask;
if ( mask == null || mask == "" )
{
_alternatives = null;
_properties = null;
}
else
{
_alternatives = mask.Split( '|' );
_properties = new BitArray( 64 );
for( int i=0; i<_alternatives.Length; i++ )
{
CalcDisplayNameFromMask( null, _alternatives [i], _properties, validate );
}
}
}
public string GetValue( Resource res )
{
if ( _alternatives == null )
{
return "";
}
for( int i=0; i<_alternatives.Length; i++ )
{
string result = CalcDisplayNameFromMask( res, _alternatives [i], null, false );
if ( result != null )
return result;
}
return "";
}
/**
* Returns true if the display name mask depends on the specified property.
*/
public bool DependsOnProperty( int propID )
{
if ( _properties == null || propID >= _properties.Length )
return false;
return _properties [propID];
}
/**
* Calculates the display name from a single mask variant, or stores the
* properties used by the mask in a bit array.
*/
private string CalcDisplayNameFromMask( Resource res, string mask, BitArray properties, bool validate )
{
int pos = 0;
bool wasSpace = false;
bool foundProps = false;
StringBuilder result = StringBuilderPool.Alloc();
try
{
while ( pos < mask.Length )
{
if ( Char.IsLetterOrDigit( mask, pos ) )
{
int propStartPos = pos;
pos++;
while( pos < mask.Length && Char.IsLetterOrDigit( mask, pos ) )
{
pos++;
}
string propName = mask.Substring( propStartPos, pos-propStartPos );
if ( CalcProperty( propName, res, result, wasSpace, properties, validate ) )
{
foundProps = true;
}
wasSpace = false;
}
else if ( mask [pos] == '{' )
{
pos++;
int propStartPos = pos;
while( pos < mask.Length && mask [pos] != '}' )
{
pos++;
}
string propName = mask.Substring( propStartPos, pos-propStartPos );
if ( mask [pos] == '}' )
{
pos++;
}
if ( CalcProperty( propName, res, result, wasSpace, properties, validate ) )
{
foundProps = true;
}
wasSpace = false;
}
else if ( mask [pos] == ' ' )
{
wasSpace = true;
pos++;
}
else
{
if ( result.Length > 0 )
{
if ( wasSpace )
result.Append( " " );
result.Append( mask [pos] );
}
pos++;
wasSpace = false;
}
}
if ( !foundProps )
return null;
return result.ToString();
}
finally
{
StringBuilderPool.Dispose( result );
}
}
private static bool CalcProperty( string propName, Resource res,
StringBuilder result, bool wasSpace, BitArray properties, bool validate )
{
bool foundProps = false;
if ( !validate && !MyPalStorage.Storage.PropTypes.Exist( propName ) )
{
return false;
}
int propID = MyPalStorage.Storage.GetPropId( propName );
if ( res != null && res.HasProp( propID ) )
{
foundProps = true;
string propValue = res.GetPropText( propID );
if ( propValue.Length > 0 )
{
if ( result.Length > 0 && wasSpace )
result.Append( " " );
result.Append( propValue );
}
}
if ( properties != null )
{
if ( properties.Length < propID+1 )
{
properties.Length = propID+1;
}
properties [propID] = true;
}
return foundProps;
}
public override string ToString()
{
return _mask;
}
}
}