ashraf tutorials
aaa  
  Home
  Contact
  Guestbook
  Coloring B/W Photo
  Photoshop Tutorials
  Illustrator Tutorials
  Flash Tutorials
  => Flash Gallery - part1
  => Flash Gallery - part2
  => Flash Gallery - part3
  => Flash Gallery - part4
  Web Design Tutorials
  Imageready Tutorials
  Aftereffect Tutorials
  3D StudioMax Tutorials
  AutoCAD Tutorials
  Tips and Tricks
Flash Gallery - part4

 Creating an XML Grid Image Gallery in Flash (ActionScript 3.0) - part 4 final

In this section of the tutorial we are going to add simple fade-in effects to all of the images in the gallery. We are going create these transitions using the Tween Class which is a class designed to make animating any property dead easy. This section will be divided into the following sections:

  1. Importing the Tween Class.
  2. Fading in each thumb once it loads.
  3. Fading in and out the entire gallery when a full image is shown and then removed.
  4. Fading in and out a full images when required.

Importing the Tween Class

The Tween Class is an ActionScript class that has no graphical assets, but it still needs to be imported for it to function. We can do that by pasting the following commands at the start of our code. We need the Tween Class itself, the Easing Classes required for determining the way the animation flows, and the Tween Event Class which is responsible for listening to Tween Events:

import fl.controls.ProgressBar;
import fl.transitions.Tween;
import fl.transitions.easing.*;
import fl.transitions.TweenEvent;

That should let us use the Tween Class as we wish in our code.

Fading in Each Thumb once it Loads

We will make the appearance of our thumbs nicer we will add a basic Tween that fade sit in instead of having it just pop up the way it does. We will execute this command to the instance of the Loader Class once it loads using the thumbLoaded() listener function:

function thumbLoaded(e:Event):void {
var my_thumb:Loader = Loader(e.target.loader);
container_mc.addChild(my_thumb);
new Tween(my_thumb, "alpha", Strong.easeIn, 0,1,0.5, true);
}
Please review the AS3 Tween Class tutorial to learn more about this subject.

Test your movie now to see each of your thumbs smoothly fade in when they finish loading.

Fading In and Out the Entire Gallery when a full image is shown

We are going to fade out all the thumbs when a full image is shown to emphasize the full image. All of the thumbs are located inside the container_mc MovieClip. This makes it possible for us to fade them all out by just fading out container_mc. We are going to execute this animation from within the callFull() listener function this way:

function callFull(e:MouseEvent):void {
var full_loader:Loader = new Loader();
var full_url = my_images[e.target.name].@FULL;
full_loader.load(new URLRequest(full_url));
full_loader.contentLoaderInfo.addEventListener(Event.INIT, fullLoaded);

var full_pb:ProgressBar = new ProgressBar();
full_pb.source = full_loader.contentLoaderInfo;
full_pb.x = (stage.stageWidth - full_pb.width)/2;
full_pb.y = (stage.stageHeight - full_pb.height)/2;
preloaders_mc.addChild(full_pb);

full_pb.addEventListener(Event.COMPLETE, donePb);

container_mc.removeEventListener(MouseEvent.CLICK, callFull);
new Tween(container_mc, "alpha", Strong.easeIn, 1,0.5,0.5, true);

}

We need to fade the container back in once the full image is removed. We can do this by executing another Tween from within the removeFull() listener function:

function removeFull(e:MouseEvent):void{
var my_loader:Loader = Loader (e.currentTarget);
my_loader.unload();
removeChild(my_loader);

container_mc.addEventListener(MouseEvent.CLICK, callFull);
new Tween(container_mc, "alpha", Strong.easeOut, 0.5,1,0.5, true);

}

You can test your movie now and click a thumb to see the gallery fade in and out as the full image is shown.

Fading In and Out the Full Image

Fading in the full image when it loads up is pretty easy and basically requires you to do the same thing you did with the thumbnails. Just execute a tween right after you add the full image to the display list from the fullLoaded() listener function:

function fullLoaded(e:Event):void{
var my_loader:Loader = Loader(e.target.loader);
addChild(my_loader);
new Tween(my_loader, "alpha", Strong.easeIn, 0,1,0.5, true);
my_loader.x = (stage.stageWidth - my_loader.width)/2;
my_loader.y = (stage.stageHeight - my_loader.height)/2;
my_loader.addEventListener(MouseEvent.CLICK,removeFull);
}

Fading the full image out is a bit more complicated because we need to unload the asset and also remove the loader completely from the display list, so doing that at the same time as the tween will not work because the object won't be on the stage once we execute the command.

To solve this problem we are going to change the contents of our removeFull() listener function so that we just fade it. First I will show you the current content of the removeFull() listener function:

function removeFull(e:MouseEvent):void{
var my_loader:Loader = Loader (e.currentTarget);
my_loader.unload();
removeChild(my_loader);

container_mc.addEventListener(MouseEvent.CLICK, callFull);
new Tween(container_mc, "alpha", Strong.easeOut, 0.5,1,0.5, true)

}

We can't unload the loader or remove it from the display list. We also can't add the container_mc event listener before the full image is also fully gone. So we are going to take these three items outs and do a fade in animation instead:

function removeFull(e:MouseEvent):void{
var my_loader:Loader = Loader (e.currentTarget);
var fade_out:Tween = new Tween(my_loader, "alpha", Strong.easeOut, 1,0,0.5, true);

new Tween(container_mc, "alpha", Strong.easeOut, 0.5,1,0.5, true)

}
Make sure you update this function so that it is exactly like the one shown above at this stage.

We put our Tween inside a variable this time to be able to register an event listener to it. We can register for the completion of the Tween animation and execute code only once the animation finishes using a TweenEvent. This way we can unload the loader, remove it from the display list, and register the container_mc event listener at the right time. Start off by registering the Tween Event this way:

function removeFull(e:MouseEvent):void{
var my_loader:Loader = Loader (e.currentTarget);
var fade_out:Tween = new Tween(my_loader, "alpha", Strong.easeOut, 1,0,0.5, true);
fade_out.addEventListener(TweenEvent.MOTION_FINISH, tweenFinished);

new Tween(container_mc, "alpha", Strong.easeOut, 0.5,1,0.5, true)

}

We now need to create the final listener function we need, type this at the bottom of your code and let it do the required actions we had earlier to remove all the unwanted assets and register the event listener back with container_mc:

function tweenFinished (e:TweenEvent):void{
var my_loader:Loader = Loader (e.target.obj);
my_loader.unload();
removeChild(my_loader);

container_mc.addEventListener(MouseEvent.CLICK, callFull);
}
obj is a Tween Class instance property that refers to the object currently being tweened.

That should do it. Test your movie, try to simulate download if you wish, and see how everything smoothly fades in and out!

Our gallery is more or less finished. In the final section of this tutorial we are going to polish it up and fix some bugs to ensure that gallery works well.

Summary of this Page

  1. Imported the Tween Class using the import directive.
  2. Faded in each thumb as it loaded.
  3. Faded in and out the entire gallery when a full image is shown.
  4. Faded in and out the full image as required.

Head to the final section of the tutorial to polish the grid gallery and wrap it up!

The final section of our tutorial will add some fine touches to the gallery to make it just a little bit nicer. Some of these touches are minor and not necessary, but the last section of this page about optimization and bug fixes is essential to ensure that the grid gallery works.

Here is the outline of this section:

  1. Using a finger cursor instead of the arrow.
  2. Creating a hover effect for the buttons.
  3. Optimizing the ActionScript code.

Using The Finger Cursor

You might have noticed that when you hover your mouse over the thumbs the cursor does not change to indicate that the object is actually a button. In AS3 this feature is optional and must be activated manually for each button you use. To enable the button cursor you simply need to set a special property called buttonMode to true for each object you would like to treat as a button.

To treat our thumbs as buttons, we need to configure the container_mc MovieClip because it is effectively the one to which the mouse event is registered with an event listener. To do this simple set the buttonMode property to true after you create the MovieClip:

function createContainer():void {
container_mc = new MovieClip();
container_mc.x = my_x;
container_mc.y = my_y;
addChild(container_mc);

container_mc.addEventListener(MouseEvent.CLICK, callFull);
container_mc.buttonMode = true;

preloaders_mc = new MovieClip();
preloaders_mc.x = container_mc.x;
preloaders_mc.y = container_mc.y;
addChild(preloaders_mc);

}

A small problem with this property is that it works even when mouse event is registered to it, so we need to disable it manually when the event listener is unregistered, and that happens in the callFull() method. So look for this method and disable this property when you unregister the mouse event listener for container_mc:

function callFull(e:MouseEvent):void {
var full_loader:Loader = new Loader();
var full_url = my_images[e.target.name].@FULL;
full_loader.load(new URLRequest(full_url));
full_loader.contentLoaderInfo.addEventListener(Event.INIT, fullLoaded);

var full_pb:ProgressBar = new ProgressBar();
full_pb.source = full_loader.contentLoaderInfo;
full_pb.x = (stage.stageWidth - full_pb.width)/2;
full_pb.y = (stage.stageHeight - full_pb.height)/2;
preloaders_mc.addChild(full_pb);

full_pb.addEventListener(Event.COMPLETE, donePb);

container_mc.removeEventListener(MouseEvent.CLICK, callFull);
container_mc.buttonMode = false;
new Tween(container_mc, "alpha", Strong.easeIn, 1,0.5,0.5, true)

}

And then enable it again when you register for the mouse event again in the tweenFinished listener function:

function tweenFinished (e:TweenEvent):void{
var my_loader:Loader = Loader (e.target.obj);
my_loader.unload();
removeChild(my_loader);

container_mc.addEventListener(MouseEvent.CLICK, callFull);
container_mc.buttonMode = true;
}

That does it for the thumbs, we now need to set this property for the full image. We cannot set the property directly on to the loader instance for the full image, because buttonMode is a MovieClip property and it does not work with a Loader. Attempting to use code will generate a compile time error.

function fullLoaded(e:Event):void{
var my_loader:Loader = Loader(e.target.loader);
addChild(my_loader);
new Tween(my_loader, "alpha", Strong.easeIn, 0,1,0.5, true);
my_loader.x = (stage.stageWidth - my_loader.width)/2;
my_loader.y = (stage.stageHeight - my_loader.height)/2;
my_loader.addEventListener(MouseEvent.CLICK,removeFull);
my_loader.buttonMode = true;
}

So don't use the code above. The solution to this problem is to create another container MovieClip to host our Loader instance and set the property of buttonMode to true from there. This is not as complicated as it sounds, but will require some changes to the code. First of all, we need to create this container MovieClip. Go to the top of your code and define a variable to host this MovieClip:

var columns:Number;
var my_x:Number;
var my_y:Number;
var my_thumb_width:Number;
var my_thumb_height:Number;
var my_images:XMLList;
var my_total:Number;

var container_mc:MovieClip;
var preloaders_mc:MovieClip;
var full_mc:MovieClip;

var x_counter:Number = 0;
var y_counter:Number = 0;

We will now create a MovieClip instance in this variable, set it up, and add it to the display list when the full image loads. This is to be done in the fullLoaded listener function:

function fullLoaded(e:Event):void{
full_mc = new MovieClip();
full_mc.buttonMode = true;
addChild (full_mc);

var my_loader:Loader = Loader(e.target.loader);
addChild(my_loader);
new Tween(my_loader, "alpha", Strong.easeIn, 0,1,0.5, true);
my_loader.x = (stage.stageWidth - my_loader.width)/2;
my_loader.y = (stage.stageHeight - my_loader.height)/2;
my_loader.addEventListener(MouseEvent.CLICK,removeFull);
}

We now need to add the instance of the Loader Class as a child of this new MovieClip. Update the addChild() line to reflect this:

function fullLoaded(e:Event):void{
full_mc = new MovieClip();
full_mc.buttonMode = true;
addChild (full_mc);
var my_loader:Loader = Loader(e.target.loader);
full_mc.addChild(my_loader); // This line was addChild(my_loade), just add full_mc. before it.
new Tween(my_loader, "alpha", Strong.easeIn, 0,1,0.5, true);
my_loader.x = (stage.stageWidth - my_loader.width)/2;
my_loader.y = (stage.stageHeight - my_loader.height)/2;
my_loader.addEventListener(MouseEvent.CLICK,removeFull);
}

This will now require us to make some more changes to our tweenFinished listener function as the loader is no longer a child of the document root but a child of the full_mc MovieClip. We also need to remove our MovieClip from the display list and delete it as it is no longer need. You can do all this by updating the tweenFinished listener function this way:

function tweenFinished (e:TweenEvent):void{
var my_loader:Loader = Loader (e.target.obj);
my_loader.unload();
full_mc.removeChild(my_loader); // This line was removeChid(my_loader), just add full_mc before it.
removeChild(full_mc);
full_mc = null;


container_mc.addEventListener(MouseEvent.CLICK, callFull);
container_mc.buttonMode = true;
}

We are done. Test your movie now to see the cursor working with all the thumbs and the full image as well!

Thumbs Hover Effect

Creating a hover effect is a relatively simply task. We are going to register for two mouse events, namely MOUSE_OVER and MOUSE_OUT and will use these to change the alpha transparency property of the thumbs to create a hover effect!

We are going to register the listener event to container_mc just like we did for the mouse click event. We are going to register two event listeners, onOver and onOut:

function createContainer():void {
container_mc = new MovieClip();
container_mc.x = my_x;
container_mc.y = my_y;
addChild(container_mc);

container_mc.addEventListener(MouseEvent.CLICK, callFull);
container_mc.addEventListener(MouseEvent.MOUSE_OVER, onOver);
container_mc.addEventListener(MouseEvent.MOUSE_OUT, onOut);

container_mc.buttonMode = true;

preloaders_mc = new MovieClip();
preloaders_mc.x = container_mc.x;
preloaders_mc.y = container_mc.y;
addChild(preloaders_mc);

}

We now need to define these two functions at the button of our code, the first will simply set the transparency to 0.5 and the other one will revert it back to 1.

function onOver (e:MouseEvent):void{
var my_thumb:Loader = Loader(e.target);
my_thumb.alpha = 0.5;
}
function onOut (e:MouseEvent):void{
var my_thumb:Loader = Loader (e.target);
my_thumb.alpha = 1;
}
Remember that target is a reference to the child and currentTarget is a reference to the object to which the event was registered. Please review our AS3 Event Handling tutorial to learn more about this topic.

You might want to register these when the full image is shown. This is done the same exact way we did it for the CLICK event, first update the callFull() listener function:

function callFull(e:MouseEvent):void {
var full_loader:Loader = new Loader();
var full_url = my_images[e.target.name].@FULL;
full_loader.load(new URLRequest(full_url));
full_loader.contentLoaderInfo.addEventListener(Event.INIT, fullLoaded);

var full_pb:ProgressBar = new ProgressBar();
full_pb.source = full_loader.contentLoaderInfo;
full_pb.x = (stage.stageWidth - full_pb.width)/2;
full_pb.y = (stage.stageHeight - full_pb.height)/2;
preloaders_mc.addChild(full_pb);

full_pb.addEventListener(Event.COMPLETE, donePb);

container_mc.removeEventListener(MouseEvent.CLICK, callFull);
container_mc.buttonMode = false;
container_mc.removeEventListener(MouseEvent.MOUSE_OVER, onOver);
container_mc.removeEventListener(MouseEvent.MOUSE_OUT, onOut);

new Tween(container_mc, "alpha", Strong.easeIn, 1,0.5,0.5, true)

}

And then add them back from within the tweenFinished listener function:

function tweenFinished (e:TweenEvent):void{
var my_loader:Loader = Loader (e.target.obj);
my_loader.unload();
full_mc.removeChild(my_loader); // This line was removeChid(my_loader), just add full_mc before it.
removeChild(full_mc);
full_mc = null;

container_mc.addEventListener(MouseEvent.CLICK, callFull);
container_mc.buttonMode = true;
container_mc.addEventListener(MouseEvent.MOUSE_OVER, onOver);
container_mc.addEventListener(MouseEvent.MOUSE_OUT, onOut);

}

 

You can now test your movie to see a nice simple hover effect over all your thumbs.

Bug Fixes and Optimizing the ActionScript (Memory Management)

There in a feature in the Flash Player called Garbage Collection, which is used to help improve the performance of a running Flash movie by removing all unnecessary content from the player's memory. This process happens at random times throughout playback and removes all objects which cannot be referred to from anywhere in the movie.

Sometimes times when you execute a large number of tweens without any reference the Flash Player will delete these tweens before they finish running which can easily mess up your movie. The solution to this problem is to save a reference to your tween to ensure that it does not get wiped out by Garbage Collection.

Because we are creating our tweens from within a loop, creating permanent variables to hold reference to them can be hard, so instead, we are going to create an array to save a reference to all of these tweens.

Start by creating a variable to hold a reference to this array:

var columns:Number;
var my_x:Number;
var my_y:Number;
var my_thumb_width:Number;
var my_thumb_height:Number;
var my_images:XMLList;
var my_total:Number;

var container_mc:MovieClip;
var preloaders_mc:MovieClip;
var full_mc:MovieClip;

var x_counter:Number = 0;
var y_counter:Number = 0;

var my_tweens:Array = [];


We will now store our variables in it by updating our thumbLoaded() listener function:

function thumbLoaded(e:Event):void {
var my_thumb:Loader = Loader(e.target.loader);
container_mc.addChild(my_thumb);
my_tweens[Number(my_thumb.name)]=new Tween(my_thumb, "alpha", Strong.easeIn, 0,1,0.5, true);
}
We use the name of our Loader instance as a number reference to position each tween in a unique array position.

We need to create a permanent variable for each of the other tweens we create in the movie, namely, the fade in and out of container_mc and full_mc. Create two variables at the start of your code to hold a reference to these two variables:

var columns:Number;
var my_x:Number;
var my_y:Number;
var my_thumb_width:Number;
var my_thumb_height:Number;
var my_images:XMLList;
var my_total:Number;

var container_mc:MovieClip;
var preloaders_mc:MovieClip;
var full_mc:MovieClip;

var x_counter:Number = 0;
var y_counter:Number = 0;

var my_tweens:Array = [];
var container_mc_tween:Tween;
var full_tween:Tween;

We will now use container_mc_tween to store a reference to that tween each time we use it. The first time is in the callFull() listener function:

function callFull(e:MouseEvent):void {
var full_loader:Loader = new Loader();
var full_url = my_images[e.target.name].@FULL;
full_loader.load(new URLRequest(full_url));
full_loader.contentLoaderInfo.addEventListener(Event.INIT, fullLoaded);

var full_pb:ProgressBar = new ProgressBar();
full_pb.source = full_loader.contentLoaderInfo;
full_pb.x = (stage.stageWidth - full_pb.width)/2;
full_pb.y = (stage.stageHeight - full_pb.height)/2;
preloaders_mc.addChild(full_pb);

full_pb.addEventListener(Event.COMPLETE, donePb);

container_mc.removeEventListener(MouseEvent.CLICK, callFull);
container_mc.buttonMode = false;
container_mc.removeEventListener(MouseEvent.MOUSE_OVER, onOver);
container_mc.removeEventListener(MouseEvent.MOUSE_OUT, onOut);
container_mc_tween = new Tween(container_mc, "alpha", Strong.easeIn, 1,0.5,0.5, true);

}

The second one is in the removeFull() listener function:

function removeFull(e:MouseEvent):void{
var my_loader:Loader = Loader (e.currentTarget);
var fade_out:Tween = new Tween(my_loader, "alpha", Strong.easeOut, 1,0,0.5, true);
fade_out.addEventListener(TweenEvent.MOTION_FINISH, tweenFinished);

container_mc_tween = new Tween(container_mc, "alpha", Strong.easeOut, 0.5,1,0.5, true);

}

Now we will turn to the full image, update the tween in the full_loaded() listener function:

function fullLoaded(e:Event):void{
full_mc = new MovieClip();
full_mc.buttonMode = true;
addChild (full_mc);
var my_loader:Loader = Loader(e.target.loader);
full_mc.addChild(my_loader); // This line was addChild(my_loade), just add full_mc. before it.
full_tween = new Tween(my_loader, "alpha", Strong.easeIn, 0,1,0.5, true);
my_loader.x = (stage.stageWidth - my_loader.width)/2;
my_loader.y = (stage.stageHeight - my_loader.height)/2;
my_loader.addEventListener(MouseEvent.CLICK,removeFull);
}

Now in the removeFull() listener function we will have to make additional changes because we already have a temporary variable. Remove that and use the new permanent variable. Here is what the new code should look like:

function removeFull(e:MouseEvent):void{
var my_loader:Loader = Loader (e.currentTarget);
full_tween = new Tween(my_loader, "alpha", Strong.easeOut, 1,0,0.5, true);
full_tween.addEventListener(TweenEvent.MOTION_FINISH, tweenFinished);

container_mc_tween = new Tween(container_mc, "alpha", Strong.easeOut, 0.5,1,0.5, true)

}

That should ensure that your gallery will work fine without the risk of having its tweens deleted by Garbage Collection. The rest of the tutorial will help you ensure that your movie efficiently manages its memory by removing all unnecessary assets and event listeners.

Optimizing ActionScript

This section will not add new visual improvements to your gallery, but it is an essential practice that will improve the chances of your gallery running well as part of a bigger application or your website, but ensuring that it manages memory issues sufficiently by doing the following:

  1. Deleting all objects once they become unnecessary.
  2. Unregistering event listeners once they become unnecessary.

This will require us to add more code to our gallery which will later on reduce the processing power required to run it as you use it.

We are going to start from the top, first of all, our instance of the URLLoader and its associated event listener are both not required once we extract the data from our XML file. So we can delete these two once that task is finished. Simply do that from the processXML() listener function by using the removeEventListener() method and then setting the value of the myXMLLoader as null:

function processXML(e:Event):void {
var myXML:XML = new XML(e.target.data);

columns = myXML.@COLUMNS;
my_x = myXML.@XPOSITION;
my_y = myXML.@YPOSITION;
my_thumb_width = myXML.@WIDTH;
my_thumb_height = myXML.@HEIGHT;
my_images = myXML.IMAGE;
my_total = my_images.length();

createContainer();
callThumbs();

myXMLLoader.removeEventListener(Event.COMPLETE, processXML);
myXMLLoader = null;


}

Next is our event listener used to check the download process of our thumbnails. These are only used once in the gallery and are never required again. We can do that from the thumbLoaded() listener function:

function thumbLoaded(e:Event):void {
var my_thumb:Loader = Loader(e.target.loader);
container_mc.addChild(my_thumb);
my_tweens[Number(my_thumb.name)]=new Tween(my_thumb, "alpha", Strong.easeIn, 0,1,0.5, true);

my_thumb.contentLoaderInfo.removeEventListener(Event.COMPLETE, thumbLoaded);
}

Next is the full image loader listener which can be removed because another one is registered each time a thumb is clicked. We can do that from the fullLoaded() listener function:

function fullLoaded(e:Event):void{
full_mc = new MovieClip();
full_mc.buttonMode = true;
addChild (full_mc);
var my_loader:Loader = Loader(e.target.loader);
full_mc.addChild(my_loader); // This line was addChild(my_loade), just add full_mc. before it.
full_tween = new Tween(my_loader, "alpha", Strong.easeIn, 0,1,0.5, true);
my_loader.x = (stage.stageWidth - my_loader.width)/2;
my_loader.y = (stage.stageHeight - my_loader.height)/2;
my_loader.addEventListener(MouseEvent.CLICK,removeFull);

my_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, fullLoaded);
}

Finally, we also need to remove the event listener registered by the full image fade out tween to check when it finishes. This can be done from the tweenFinished()listener function:

function tweenFinished (e:TweenEvent):void{
var my_loader:Loader = Loader (e.target.obj);
my_loader.unload();
full_mc.removeChild(my_loader); // This line was removeChid(my_loader), just add full_mc before it.
removeChild(full_mc);
full_mc = null;

container_mc.addEventListener(MouseEvent.CLICK, callFull);
container_mc.buttonMode = true;
container_mc.addEventListener(MouseEvent.MOUSE_OVER, onOver);
container_mc.addEventListener(MouseEvent.MOUSE_OUT, onOut);

var my_tween:Tween = Tween(e.target);
my_tween.removeEventListener(TweenEvent.MOTION_FINISH, tweenFinished);

}

Lets not also forget that our preloaders have event listeners registered to them. Remove this event listener from within the donePb listener function:

function donePb (e:Event):void{
var my_pb:ProgressBar = ProgressBar(e.target);
preloaders_mc.removeChild(my_pb);
my_pb.removeEventListener(Event.COMPLETE, donePb);
}

And with that you complete this section. The gird gallery is now optimized and ready for you to use!

This concludes our grid gallery tutorial, congratulations for completing the whole thing. You can download the final source file from here.


Thank you.

 
Clock  
   
Where are you?  
  IP  
Today, there have been 9 visitors (10 hits) on this page!
This website was created for free with Own-Free-Website.com. Would you also like to have your own website?
Sign up for free