using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media.Media3D;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using Point2D = System.Windows.Point;
using System.IO;
using BSE.CoverFlow.WPFLib.Properties;
using System.Diagnostics;
using System.Windows.Markup;
using System.Windows.Threading;
using BSE.Platten.BO;
namespace BSE.CoverFlow.WPFLib
{
/// <summary>
/// Contains the cover images and the animation properties for one coverflow object.
/// </summary>
public class CoverItem : IDisposable
{
#region FieldsPrivate
private readonly string m_strCacheDirectoryName;
private CreateImageSourceThread m_createImageSourceThread;
private ImageSource m_defaultImageSource;
// Track whether Dispose has been called.
private bool m_bDisposed;
#endregion
#region Properties
/// <summary>
/// Gets or sets the current position of the coveritem in the Visual3DCollection.
/// </summary>
public int Position
{
get;
set;
}
/// <summary>
/// Gets or sets the AlbumId for the cover.
/// </summary>
public int TitelId
{
get;
set;
}
/// <summary>
/// Gets or sets the <see cref="ModelVisual3D"/>.
/// </summary>
public ModelVisual3D ModelVisual3D
{
get;
set;
}
/// <summary>
/// Gets or sets the Viewport3DIndex for the animation.
/// </summary>
public int Viewport3DIndex
{
get;
set;
}
/// <summary>
/// Gets or sets the <see cref="Storyboard"/>.
/// </summary>
public Storyboard Storyboard
{
get;
set;
}
#endregion
#region MethodsPublic
/// <summary>
/// Constructor for an CoverItem.
/// </summary>
/// <param name="modelVisual3D"><see cref="Visual"/> that contains 3-D models.</param>
/// <param name="storyboard">A container timeline that provides object and property targeting information for its child animations.</param>
/// <param name="strCacheDirectoryName">The name of the cache directory.</param>
/// <param name="defaultImageSource">The default imagesource if there is no other cover image</param>
/// <param name="iAlbumId">The AlbimId of the cover record in the database.</param>
/// <param name="iPosition">The position of the CoverItem in the Visual3DCollection.</param>
public CoverItem(ModelVisual3D modelVisual3D, Storyboard storyboard, string strCacheDirectoryName, ImageSource defaultImageSource, int iAlbumId, int iPosition, string strConnection)
{
if (defaultImageSource == null)
{
throw new ArgumentException(
string.Format(
System.Globalization.CultureInfo.CurrentUICulture,
Resources.IDS_ArgumentException,
"defaultImageSource"));
}
using (MemoryStream memoryStream = new MemoryStream())
{
XamlWriter.Save(modelVisual3D, memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
this.ModelVisual3D = XamlReader.Load(memoryStream) as ModelVisual3D;
}
using (MemoryStream memoryStream = new MemoryStream())
{
XamlWriter.Save(storyboard, memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
this.Storyboard = XamlReader.Load(memoryStream) as Storyboard;
}
this.Position = iPosition;
this.m_strCacheDirectoryName = strCacheDirectoryName;
this.TitelId = iAlbumId;
this.m_defaultImageSource = defaultImageSource;
double dYRotation = 0.0;
double dOffsetX = 0.0;
double dOffsetY = 0.0;
double dOffsetZ = 0.0;
GetOffsetsFromPosition(this.Position, out dYRotation, out dOffsetX, out dOffsetY, out dOffsetZ);
Model3DGroup model3DGroup = this.ModelVisual3D.Content as Model3DGroup;
GeometryModel3D geometryModel3D = model3DGroup.Children[1] as GeometryModel3D;
if (geometryModel3D != null)
{
if (geometryModel3D.Material != null)
{
geometryModel3D.Material = null;
geometryModel3D.Material = LoadImageMirror(defaultImageSource);
}
}
Transform3DGroup transform3DGroup = model3DGroup.Transform as Transform3DGroup;
RotateTransform3D rotateTransform3D = transform3DGroup.Children[0] as RotateTransform3D;
if (rotateTransform3D != null)
{
AxisAngleRotation3D axisAngleRotation3D = rotateTransform3D.Rotation as AxisAngleRotation3D;
axisAngleRotation3D.Angle = dYRotation;
}
TranslateTransform3D translateTransform3D = transform3DGroup.Children[1] as TranslateTransform3D;
if (translateTransform3D != null)
{
translateTransform3D.OffsetX = dOffsetX;
translateTransform3D.OffsetZ = dOffsetZ;
}
string strImageFileName = Path.Combine(this.m_strCacheDirectoryName, this.TitelId + Constants.PngFileFormatSuffix);
this.m_createImageSourceThread = new CreateImageSourceThread(
strImageFileName, this.TitelId, strConnection);
this.m_createImageSourceThread.ImageSourceCreated += new EventHandler<EventArgs>(ImageSourceCreated);
}
/// <summary>
/// Matches the CoverItem with the clicked CoverItem
/// </summary>
/// <param name="modelVisual3D"><see cref="Visual"/>that contains 3-D models.</param>
/// <returns>True if when match else false</returns>
public bool Matches(ModelVisual3D modelVisual3D)
{
if (this.ModelVisual3D.Equals(modelVisual3D) == true)
{
return true;
}
return false;
}
/// <summary>
/// Gets the animation offsets for the CoverItem dependent to the position in its parent list
/// </summary>
/// <param name="iPosition">The position of the CoverItem in the Visual3DCollection.</param>
/// <param name="dYRotation">The value for the rotation animation.</param>
/// <param name="dOffsetX">The value for the x- axis animation.</param>
/// <param name="dOffsetY">The value for the x- axis animation.</param>
/// <param name="dOffsetZ">The value for the z- axis animation.</param>
public static void GetOffsetsFromPosition(int iPosition, out double dYRotation, out double dOffsetX, out double dOffsetY,out double dOffsetZ)
{
dYRotation = 0.0;
dOffsetX = 0.0;
dOffsetY = 0.0;
dOffsetZ = 1.0;
int num = Math.Abs(iPosition) - 1;
if (iPosition > 0)
{
dYRotation = -72.0;
dOffsetX = 1.8 + num;
dOffsetZ = -0.0;
}
if (iPosition < 0)
{
dYRotation = 72.0;
dOffsetX = -1.8 - num;
dOffsetZ = -0.0;
}
}
/// <summary>
/// Checks whether the image exists in the filesystem
/// </summary>
/// <param name="strFileName">The name of the image file</param>
/// <returns>True if exits else false</returns>
public static bool ExistsImageFile(string strFileName)
{
FileInfo fileInfo = new FileInfo(strFileName);
if (fileInfo.Exists == true)
{
return true;
}
return false;
}
// Implement IDisposable.
// Do not make this method virtual.
// A derived class should not be able to override this method.
public void Dispose()
{
Dispose(true);
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SupressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
#endregion
#region MethodsProtected
// Dispose(bool disposing) executes in two distinct scenarios.
// If disposing equals true, the method has been called directly
// or indirectly by a user's code. Managed and unmanaged resources
// can be disposed.
// If disposing equals false, the method has been called by the
// runtime from inside the finalizer and you should not reference
// other objects. Only unmanaged resources can be disposed.
protected virtual void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if (this.m_bDisposed == false)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if (disposing)
{
// Dispose managed resources.
if (this.m_createImageSourceThread != null)
{
this.m_createImageSourceThread.ImageSourceCreated -= new EventHandler<EventArgs>(ImageSourceCreated);
this.m_createImageSourceThread.Dispose();
}
if (this.ModelVisual3D != null)
{
Model3DGroup model3DGroup = this.ModelVisual3D.Content as Model3DGroup;
if (model3DGroup != null)
{
GeometryModel3D geometryModel3D = model3DGroup.Children[0] as GeometryModel3D;
if (geometryModel3D != null)
{
if (geometryModel3D.Material != null)
{
geometryModel3D = null;
}
geometryModel3D = null;
}
GeometryModel3D geometryModel3DMirror = model3DGroup.Children[1] as GeometryModel3D;
if (geometryModel3DMirror != null)
{
if (geometryModel3DMirror.Material != null)
{
geometryModel3DMirror = null;
}
geometryModel3DMirror = null;
}
Transform3DGroup transform3DGroup = model3DGroup.Transform as Transform3DGroup;
if (transform3DGroup != null)
{
RotateTransform3D rotateTransform3D = transform3DGroup.Children[0] as RotateTransform3D;
if (rotateTransform3D != null)
{
rotateTransform3D = null;
}
TranslateTransform3D translateTransform3D = transform3DGroup.Children[1] as TranslateTransform3D;
if (translateTransform3D != null)
{
translateTransform3D = null;
}
transform3DGroup = null;
}
model3DGroup = null;
}
this.ModelVisual3D = null;
}
if (this.Storyboard != null)
{
this.Storyboard = null;
}
if (this.m_defaultImageSource != null)
{
this.m_defaultImageSource = null;
}
}
this.m_bDisposed = true;
}
}
#endregion
#region MethodsPrivate
private void ImageSourceCreated(object sender, EventArgs e)
{
using (CreateImageSourceThread createImageSourceThread = sender as CreateImageSourceThread)
{
if (createImageSourceThread != null)
{
createImageSourceThread.ImageSourceCreated -= new EventHandler<EventArgs>(ImageSourceCreated);
System.Threading.ThreadStart threadStart = delegate()
{
string strImageFileName = Path.Combine(this.m_strCacheDirectoryName, this.TitelId + Constants.PngFileFormatSuffix);
ImageSource imageSource = GetImageSource(strImageFileName);
if (imageSource != null)
{
if (this.ModelVisual3D != null)
{
this.ModelVisual3D.Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Normal,
(System.Threading.ThreadStart)delegate()
{
LoadImageIntoModel3DGroup(imageSource);
});
}
}
};
new System.Threading.Thread(threadStart).Start();
}
}
}
private void LoadImageIntoModel3DGroup(ImageSource imageSource)
{
if (imageSource != null)
{
Model3DGroup content = this.ModelVisual3D.Content as Model3DGroup;
if (content != null)
{
GeometryModel3D geometryModel3D = content.Children[0] as GeometryModel3D;
if (geometryModel3D != null)
{
if (geometryModel3D.Material != null)
{
geometryModel3D.Material = null;
geometryModel3D.Material = LoadImage(imageSource);
}
}
GeometryModel3D geometryModel3DMirror = content.Children[1] as GeometryModel3D;
if (geometryModel3DMirror != null)
{
if (geometryModel3DMirror.Material != null)
{
geometryModel3DMirror.Material = null;
geometryModel3DMirror.Material = LoadImageMirror(imageSource);
}
}
}
imageSource = null;
}
}
private static ImageSource GetImageSource(string strFileName)
{
if (ExistsImageFile(strFileName) == true)
{
try
{
BitmapImage bitmapImage = new BitmapImage();
Uri uri = new Uri(strFileName, UriKind.RelativeOrAbsolute);
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.UriSource = uri;
bitmapImage.EndInit();
bitmapImage.Freeze();
return bitmapImage;
}
catch (Exception exception)
{
throw new Exception("GetImageSource" + exception.Message);
}
}
return null;
}
private static Material LoadImage(ImageSource imageSource)
{
return new DiffuseMaterial(new ImageBrush(imageSource));
}
private static Material LoadImageMirror(ImageSource imageSource)
{
ImageBrush imageBrush = new ImageBrush(imageSource);
imageBrush.Opacity = 0.9;
LinearGradientBrush linearGradientBrush = new LinearGradientBrush();
linearGradientBrush.StartPoint = new System.Windows.Point(0, 1);
linearGradientBrush.EndPoint = new System.Windows.Point(0, 0);
linearGradientBrush.GradientStops.Add(new GradientStop(Colors.White, 0));
linearGradientBrush.GradientStops.Add(new GradientStop(Colors.Transparent, 0.4));
System.Windows.Shapes.Rectangle imageRectangle = new System.Windows.Shapes.Rectangle();
imageRectangle.Width = imageSource.Width;
imageRectangle.Height = imageSource.Height;
imageRectangle.OpacityMask = linearGradientBrush;
imageRectangle.Fill = imageBrush;
imageRectangle.Arrange(
new System.Windows.Rect(
new System.Windows.Point(0, 0),
new System.Windows.Size(imageSource.Width, imageSource.Height))
);
imageRectangle.UpdateLayout();
linearGradientBrush = null;
RenderTargetBitmap renderBitmap = new RenderTargetBitmap(
(int)imageRectangle.Width,
(int)imageRectangle.Height, 96, 96, PixelFormats.Pbgra32);
renderBitmap.Render(imageRectangle);
imageRectangle = null;
imageBrush = null;
imageBrush = new ImageBrush(renderBitmap);
renderBitmap = null;
return new DiffuseMaterial(imageBrush);
}
#endregion
}
}