<repo_name>no1spirite/Portfolio<file_sep>/Portfolio.Web/Extensions/WebPageExtensions.cs
﻿namespace BibleGravy.Extensions
{
    using System.Collections.Generic;
    using System.Text;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.WebPages;

    using RedBadger.Web.ScriptDependencyResolver;

    public static class WebPageExtentions
    {
        public static IHtmlString WriteScriptTags(this WebViewPage page, string scriptsDirectory)
        {

            string appRoot = page.Context.Server.MapPath("~/").ToLower();
            string scriptsPath = page.Context.Server.MapPath(scriptsDirectory);
            IEnumerable<string> allScripts = EnumerateScriptFiles(appRoot, scriptsPath);
            var sb = new StringBuilder();
            foreach (string file in allScripts)
            {
                sb.AppendLine(GetScriptTag(MapToVirtualPath(page.Context, appRoot, file)));
            }
            return MvcHtmlString.Create(sb.ToString());
        }

        private static IEnumerable<string> EnumerateScriptFiles(string appRoot, string scriptsPath)
        {
            var resolver = new Resolver(appRoot, scriptsPath, "*.js");
            return resolver.Resolve();
        }

        private static string GetScriptTag(string url)
        {
            return string.Format("<script type=\"text/javascript\" src=\"{0}\"></script>", url);
        }

        private static string MapToVirtualPath(HttpContextBase context, string appRoot, string file)
        {
            var url = "~/" + file.Replace(appRoot, "").Replace(@"\", "/");
            return UrlHelper.GenerateContentUrl(url, context);
        }
    }
}<file_sep>/Portfolio.Web/Global.asax.cs
﻿namespace Portfolio.Web
{
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;

    using Castle.Windsor;
    using Castle.Windsor.Installer;

    using Portfolio.Web.Factories;

    public class MvcApplication : HttpApplication
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });

            routes.MapRoute(
                "Default",
                // Route name
                "{controller}/{action}/{id}",
                // URL with parameters
                new { controller = "Blog", action = "Blog", id = UrlParameter.Optional } // Parameter defaults
                );
        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);

            ConfigureContainer();
        }

        private IWindsorContainer container;

        private void ConfigureContainer()
        {
            this.container = new WindsorContainer();

            var controllerFactory = new WindsorControllerFactory(this.container.Kernel);
            ControllerBuilder.Current.SetControllerFactory(controllerFactory);
            this.container.Install(FromAssembly.This());
        }
    }
}<file_sep>/Portfolio.Domain/Services/ResourceManager.cs
﻿namespace Portfolio.Domain.Services
{
    using System.Data;
    using System.Data.Objects;
    using System.Data.SqlClient;

    using Portfolio.Domain.Data;

    public class ResourceManager : IResourceManager
    {
        private readonly PortfolioEntities portfolioEntities;

        public ResourceManager()
        {
            this.portfolioEntities = new PortfolioEntities();
        }

        public ObjectResult<T> Get<T>(IResourceManagerOptions options) where T : IDeserializable, new()
        {
            ObjectResult<T> results =
                this.portfolioEntities.ExecuteStoreQuery<T>(
                    string.Format("exec {0} {1}", options.ProcedureName, this.ConvertOptions(options.Parameters)),
                    options.Parameters);
            return results;
        }

        private string ConvertOptions(object[] parameters)
        {
            string paramString = string.Empty;
            if (parameters != null)
            {
                int count = 1;
                foreach (SqlParameter sqlParameter in parameters)
                {
                    paramString += sqlParameter.ParameterName + (count == parameters.Length ? string.Empty : ", ")
                                   + (sqlParameter.Direction == ParameterDirection.Output ? " OUT" : string.Empty);
                    count++;
                }
            }
            return paramString;
        }
    }
}<file_sep>/Portfolio.Domain/Services/IBlogService.cs
namespace Portfolio.Domain.Services
{
    using System.Collections.Generic;

    using Portfolio.Domain.Resources;

    public interface IBlogService
    {
        List<Comment> PostComment(int blogId, string name, string commentText, int lastCommentId);

        IList<BlogEntry> GetBlogs();

        IList<Comment> GetComments(int blogId);
    }
}<file_sep>/Portfolio.Web/app.js
// ~/blog.js
/// <reference path="~/Scripts/amplify.js" />
/// <reference path="~/Scripts/knockout-2.1.0.debug.js" />

/// <reference path="~/Scripts/SyntaxHighlighter/shCore.js" />
/// <reference path="~/Scripts/SyntaxHighlighter/shBrushCSharp.js" />

var Blog = function () {
    var that = this;
    this.blogEntries = ko.observableArray([]);
    this.showComments = ko.observable(false);
    $('div.blog').find('pre').addClass('brush: csharp');
    $('code').contents().unwrap();
    SyntaxHighlighter.highlight();

    amplify.request.define("getComments", "ajax", {
        url: "/blog/comments",
        dataType: "html",
        type: "GET",
        decoder: "appEnvelope"
    });

    this.toggleComments = function (d, e) {
        var $anchor = $(e.target);
        if ($anchor.text() === 'Show comments') {
            $anchor.text('Hide comments');
            if (!$anchor.closest('div.blogEntryContainer').children('div.comments').get(0)) {
                var blogId = $anchor.closest('li.blogEntry').data('id');
                amplify.request({
                    resourceId: 'getComments',
                    data: { blogId: blogId },
                    success: function (comments) {
                        $anchor.closest('div.blogEntryContainer').append(comments);
                        $anchor.closest('div.blogEntryContainer').children('div.comments').show('fast');
                        that.showComments(true);
                    }
                });
            } else {
                $anchor.closest('div.blogEntryContainer').children('div.comments').show('fast');
                that.showComments(true);
            }
        } else {
            $anchor.text('Show comments');
            $anchor.closest('div.blogEntryContainer').children('div.comments').hide('fast');
            that.showComments(false);
        }

        e.preventDefault();
    };
};
// ~/comments.js
/// <reference path="~/Scripts/Amplify.js" />
/// <reference path="~/Scripts/knockout-2.1.0.js" />
/// <reference path="~/Scripts/underscore.js" />
/// <reference path="~/Scripts/dateformat.js" />

/// <reference path="~/Scripts/Custom/Blog.js" />

var Comments = function () {
    var that = this;
    this.commentsObservable = ko.observableArray([]);
    this.name = ko.observable();
    this.commentText = ko.observable();
    this.canSubmit = ko.observable(true);
    var result = "BlogObject" instanceof Blog;

    amplify.request.define("putComment", "ajax", {
        url: "/blog/putComment",
        type: "PUT",
        decoder: "appEnvelope"
    });

    this.addNewComment = function (d, e) {
        amplify.request({
            resourceId: 'putComment',
            data: { blogId: $(d).data('id'), name: that.name(), commentText: that.commentText(), 
                    lastCommentId: that.commentsObservable().length > 0 ? that.commentsObservable()[that.commentsObservable().length - 1].id() : 0 },
            success: function (newComments) {
                _.each(newComments, function (newComment) {
                    var regEx = /-?\d+/;
                    var m = regEx.exec(newComment.Date);
                    var formattedDate = new Date(parseInt(m[0])).format('mmm dd, yyyy "at" hh:mm TT');
                    that.commentsObservable.push({ id: ko.observable(newComment.Id), author: ko.observable(newComment.Author), date: ko.observable(formattedDate), commentText: ko.observable(newComment.Text) });
                });
            }
        });
    };
};
// ~/knockoutextensions.js
/// <reference path="~/Scripts/knockout-2.1.0.debug.js" />
/// <reference path="~/Scripts/jquery-1.7.2-vsdoc.js" />
/// <reference path="~/Scripts/underscore.js" />

ko.bindingHandlers.slideVisible = {
    init: function (element, valueAccessor) {
        var $element = $(element);
        if (ko.utils.unwrapObservable(valueAccessor())) {
            $element.show();
        } else {
            $element.hide();
        }
    },
    update: function (element, valueAccessor) {
        var $element = $(element);
        if (ko.utils.unwrapObservable(valueAccessor())) {
            $('body').queue(function (next) {
                $element.slideDown("fast", function () {
                    next();
                });
            });
        } else {
            $('body').queue(function (next) {
                $element.slideUp("fast", function () {
                    next();
                });
            });
        }
    }
};

ko.bindingHandlers['foreachPE'] = {
    'init': function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        function clone(obj) {
            if (obj == null || typeof (obj) != 'object')
                return obj;

            var temp = new obj.constructor();
            for (var key in obj)
                temp[key] = clone(obj[key]);

            return temp;
        }
        
        var observableArray = valueAccessor();
        if (ko.isWriteableObservable(observableArray)) {
            _.forEach($(element).children(), function (child) {
                var bindingObject = {};
                _.forEach($(child).find('*'), function (ancestor) {
                    if ($(ancestor).attr('data-bind')) {
                        var jsonObject = $.parseJSON("{" + $(ancestor).attr('data-bind').replace(/'/g, '"').replace(/[\(\)]/g, '"') + "}");
                        _.forEach(jsonObject, function (value, key) {
                            try {
                                if (key === 'click') {
                                    $.extend(true, bindingObject, viewModel);
                                    //bindingObject[value] = $.extend(true, viewModel[value]);
                                    //bindingObject[value] = viewModel[value].apply(viewModel);
                                    //bindingObject[value] = clone(viewModel[value]);
                                    //bindingObject[value] = viewModel[value];
                                } 
                                else if(key === 'visible') {
                                    bindingObject[value] = ko.observable(true);
                                }
                                else {
                                    bindingObject[value] = ko.observable($(ancestor)[key]());
                                }
                            } catch (e) {
                                console.log("foreachPE - problem handling " + key + " binding. Error: " + e);
                            }
                        });
                    }
                });
                observableArray.push(bindingObject);
            });
        }
        var children = $(element).children();
        $(element).empty();
        $(element).append(children[0]);
        return ko.bindingHandlers['template']['init'](element, ko.bindingHandlers['foreach'].makeTemplateValueAccessor(valueAccessor));
    },
    'update': function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        return ko.bindingHandlers['template']['update'](element, ko.bindingHandlers['foreach'].makeTemplateValueAccessor(valueAccessor), allBindingsAccessor, viewModel, bindingContext);
    }
};
// ~/projects.js
/// <reference path="~/Scripts/jquery.fancybox.pack.js" />
/// <reference path="~/Scripts/jquery-1.7.2-vsdoc.js" />

var Projects = function() {
    $('a.fancybox').fancybox({
        openEffect: 'none',
        closeEffect: 'none'
    });
};
// ~/blogentry.js
var BlogEntry = function (entry) {
//    this.title = entry.Title;
//    this.blogText = entry.Blogtext;
//    this.date = entry.Date;
//    this.author = entry.Author;
};
<file_sep>/Portfolio.Domain/Services/ResourceManagerOptions.cs
﻿namespace Portfolio.Domain.Services
{
    public class ResourceManagerOptions : IResourceManagerOptions
    {
        public object[] Parameters { get; set; }

        public string ProcedureName { get; set; }
    }
}<file_sep>/Portfolio.Domain/Services/IResourceManager.cs
namespace Portfolio.Domain.Services
{
    using System.Data.Objects;

    public interface IResourceManager
    {
        ObjectResult<T> Get<T>(IResourceManagerOptions options) where T : IDeserializable, new();
    }
}<file_sep>/Portfolio.Domain/Services/IResourceManagerOptions.cs
namespace Portfolio.Domain.Services
{
    public interface IResourceManagerOptions
    {
        object[] Parameters { get; set; }

        string ProcedureName { get; set; }
    }
}<file_sep>/Portfolio.Web/Controllers/ToolsController.cs
﻿namespace Portfolio.Web.Controllers
{
    using System.Web.Mvc;

    public class ToolsController : Controller
    {
        public ActionResult Tools()
        {
            return this.View();
        }
    }
}<file_sep>/Portfolio.Domain/IDeserializable.cs
﻿namespace Portfolio.Domain
{
    public interface IDeserializable
    {
         
    }
}<file_sep>/Portfolio.Web/Installers/DomainAssemblyInstaller.cs
﻿namespace Portfolio.Web.Installers
{
    using Castle.MicroKernel.Registration;
    using Castle.MicroKernel.SubSystems.Configuration;
    using Castle.Windsor;

    using Portfolio.Domain.Services;

    public class DomainAssemblyInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(Component.For<IResourceManager>().ImplementedBy<ResourceManager>().LifeStyle.Transient);

            container.Register(
                AllTypes.FromAssemblyContaining<ResourceManager>().Where(n => n.Name.EndsWith("Service")).WithService.
                    FirstInterface().LifestyleTransient());
        }
    }
}<file_sep>/Portfolio.Domain/Services/BlogService.cs
﻿namespace Portfolio.Domain.Services
{
    using System.Collections.Generic;
    using System.Data.SqlClient;
    using System.Linq;

    using Portfolio.Domain.Resources;

    public class BlogService : IBlogService
    {
        private readonly IResourceManager resourceManager;

        public BlogService(IResourceManager resourceManager)
        {
            this.resourceManager = resourceManager;
        }

        public List<Comment> PostComment(int blogId, string name, string commentText, int lastCommentId)
        {
            List<Comment> results =
                this.resourceManager.Get<Comment>(
                    new ResourceManagerOptions
                        {
                            ProcedureName = "PutComment",
                            Parameters =
                                new object[]
                                    {
                                        new SqlParameter("@id", blogId), 
                                        new SqlParameter("@name", name),
                                        new SqlParameter("@commentText", commentText),
                                        new SqlParameter("@lastCommentId", lastCommentId)
                                    }
                        }).ToList();
            return results;
        }

        public IList<BlogEntry> GetBlogs()
        {
            List<BlogEntry> results =
                this.resourceManager.Get<BlogEntry>(new ResourceManagerOptions { ProcedureName = "GetBlogEntries" }).
                    ToList();
            return results;
        }

        public IList<Comment> GetComments(int blogId)
        {
            List<Comment> results =
                this.resourceManager.Get<Comment>(
                    new ResourceManagerOptions
                        { ProcedureName = "GetComments", Parameters = new object[] { new SqlParameter("@id", blogId) } })
                    .ToList();
            return results;
        }
    }
}<file_sep>/Portfolio.Domain/Resources/BlogEntry.cs
namespace Portfolio.Domain.Resources
{
    using System;

    public class BlogEntry : IDeserializable
    {
        public String Author { get; set; }

        public String BlogText { get; set; }

        public DateTime Date { get; set; }

        public int Id { get; set; }

        public String Title { get; set; }

        public int CommentCount { get; set; }
    }
}<file_sep>/Portfolio.Web/Controllers/BlogController.cs
﻿namespace Portfolio.Web.Controllers
{
    using System.Web.Mvc;

    using Portfolio.Domain.Services;

    public class BlogController : Controller
    {
        private readonly IBlogService blogService;

        public BlogController(IBlogService blogService)
        {
            this.blogService = blogService;
        }

        public ActionResult Blog()
        {
            var md = new MarkdownSharp.Markdown();
            var blogEntries = this.blogService.GetBlogs();
            foreach (var blogEntry in blogEntries)
            {
                blogEntry.BlogText = md.Transform(blogEntry.BlogText);
                blogEntry.Title = md.Transform(blogEntry.Title);

            }
            this.View().ViewData["blogEntries"] = blogEntries;
            return this.View();
        }

        [HttpGet]
        public ActionResult GetBlogEntries()
        {
            var md = new MarkdownSharp.Markdown();
            var blogEntries = this.blogService.GetBlogs();
            foreach (var blogEntry in blogEntries)
            {
                blogEntry.BlogText = md.Transform(blogEntry.BlogText);

            }
            JsonResult blogs = this.Json(blogEntries
                , JsonRequestBehavior.AllowGet);
            return blogs;
        }

        [HttpPut]
        public ActionResult PutComment(int blogId, string name, string commentText, int lastCommentId)
        {
            var newComment = this.blogService.PostComment(blogId, name, commentText, lastCommentId);
            JsonResult comment = this.Json(newComment
                , JsonRequestBehavior.AllowGet);
            return comment;
        }

        public ActionResult Comments(int blogId)
        {
            this.PartialView().ViewData["comments"] = this.blogService.GetComments(blogId);
            this.PartialView().ViewData["blogId"] = blogId;
            return this.PartialView();
        }
    }
}<file_sep>/Portfolio.Web/Modules/CustomHeaderModule.cs
﻿namespace Portfolio.Web.Modules
{
    using System;
    using System.Web;

    public class CustomHeaderModule : IHttpModule
    {
        public void Init(HttpApplication application)
        {
            application.PostReleaseRequestState += this.application_PostReleaseRequestState;

        }

        public void Dispose()
        {
        }

        void application_PostReleaseRequestState(object sender, EventArgs e)
        {
            HttpContext.Current.Response.Headers.Remove("Server");
            HttpContext.Current.Response.Headers.Remove("X-AspNet-Version");
            HttpContext.Current.Response.Headers.Remove("ETag");
        }
    }
}<file_sep>/Portfolio.Web/Installers/ControllerInstaller.cs
﻿namespace Portfolio.Web.Installers
{
    using System.Web.Mvc;

    using Castle.MicroKernel.Registration;
    using Castle.MicroKernel.SubSystems.Configuration;
    using Castle.Windsor;

    using Portfolio.Web.Controllers;

    public class ControllersInstaller : IWindsorInstaller
    {
        /// <summary>
        /// Installs the controllers
        /// </summary>
        /// <param name="container"></param>
        /// <param name="store"></param>
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(this.FindControllers().LifestyleTransient());
        }

        /// <summary>
        /// Find controllers within this assembly in the same namespace as HomeController
        /// </summary>
        /// <returns></returns>
        private BasedOnDescriptor FindControllers()
        {
            return AllTypes.FromThisAssembly()
                .BasedOn<IController>()
                .If(Component.IsInSameNamespaceAs<HomeController>())
                .If(t => t.Name.EndsWith("Controller"));
        }

    }
}<file_sep>/Portfolio.Web/Controllers/CommentController.cs
﻿namespace Portfolio.Web.Controllers
{
    using System.Web.Mvc;

    public class CommentController : Controller
    {
        [HttpPost]
        public void PostComment()
        {
        }
    }
}