private XmlRpcStruct NewTopic(int forumId, string subject, string body, string prefixId, IEnumerable<string> attachmentIds, string groupId)
        {
            var aftContext = ActiveForumsTapatalkModuleContext.Create(Context);

            Context.Response.AddHeader("Mobiquo_is_login", aftContext.UserId > 0 ? "true" : "false");

            var portalId = aftContext.Module.PortalID;
            var forumModuleId = aftContext.ModuleSettings.ForumModuleId;

            var fc = new AFTForumController();

            var forumInfo = fc.GetForum(portalId, forumModuleId, forumId);

            // Verify Post Permissions
            if (!ActiveForums.Permissions.HasPerm(forumInfo.Security.Create, aftContext.ForumUser.UserRoles))
            {
                return new XmlRpcStruct
                                {
                                    {"result", "false"}, //"true" for success
                                    {"result_text", "Not Authorized to Post".ToBytes()}, 
                                };
            }

            // Build User Permissions
            var canModApprove = ActiveForums.Permissions.HasPerm(forumInfo.Security.ModApprove, aftContext.ForumUser.UserRoles);
            var canTrust = ActiveForums.Permissions.HasPerm(forumInfo.Security.Trust, aftContext.ForumUser.UserRoles);
            var userProfile = aftContext.UserId > 0 ? aftContext.ForumUser.Profile : new UserProfileInfo { TrustLevel = -1 };
            var userIsTrusted = Utilities.IsTrusted((int)forumInfo.DefaultTrustValue, userProfile.TrustLevel, canTrust, forumInfo.AutoTrustLevel, userProfile.PostCount);

            // Determine if the post should be approved
            var isApproved = !forumInfo.IsModerated || userIsTrusted || canModApprove;

            var mainSettings = new SettingsInfo { MainSettings = new Entities.Modules.ModuleController().GetModuleSettings(forumModuleId) };

            var dnnUser = Entities.Users.UserController.GetUserById(portalId, aftContext.UserId);

            var authorName = GetAuthorName(mainSettings, dnnUser);

            var themePath = string.Format("{0}://{1}{2}", Context.Request.Url.Scheme, Context.Request.Url.Host, VirtualPathUtility.ToAbsolute("~/DesktopModules/activeforums/themes/" + mainSettings.Theme + "/"));

            subject = Utilities.CleanString(portalId, subject, false, EditorTypes.TEXTBOX, forumInfo.UseFilter, false, forumModuleId, themePath, false);
            body = Utilities.CleanString(portalId, TapatalkToHtml(body), forumInfo.AllowHTML, EditorTypes.HTMLEDITORPROVIDER, forumInfo.UseFilter, false, forumModuleId, themePath, forumInfo.AllowEmoticons);

            // Create the topic

            var ti = new TopicInfo();
            var dt = DateTime.Now;
            ti.Content.DateCreated = dt;
            ti.Content.DateUpdated = dt;
            ti.Content.AuthorId = aftContext.UserId;
            ti.Content.AuthorName = authorName;
            ti.Content.IPAddress = Context.Request.UserHostAddress;
            ti.TopicUrl = string.Empty;
            ti.Content.Body = body;
            ti.Content.Subject = subject;
            ti.Content.Summary = string.Empty;

            ti.IsAnnounce = false;
            ti.IsPinned = false;
            ti.IsLocked = false;
            ti.IsDeleted = false;
            ti.IsArchived = false;

            ti.StatusId = -1;
            ti.TopicIcon = string.Empty;
            ti.TopicType = 0;

            ti.IsApproved = isApproved;

            // Save the topic
            var tc = new TopicsController();
            var topicId = tc.TopicSave(portalId, ti);
            ti = tc.Topics_Get(portalId, forumModuleId, topicId, forumId, -1, false);

            if (ti == null)
            {
                return new XmlRpcStruct
                                {
                                    {"result", "false"}, //"true" for success
                                    {"result_text", "Error Creating Post".ToBytes()}, 
                                };
            }

            // Update stats
            tc.Topics_SaveToForum(forumId, topicId, portalId, forumModuleId);
            if (ti.IsApproved && ti.Author.AuthorId > 0)
            {
                var uc = new ActiveForums.Data.Profiles();
                uc.Profile_UpdateTopicCount(portalId, ti.Author.AuthorId);
            }


            try
            {
                // Clear the cache
                var cachekey = string.Format("AF-FV-{0}-{1}", portalId, forumModuleId);
                DataCache.CacheClearPrefix(cachekey);

                // Subscribe the user if they have auto-subscribe set.
                if (userProfile.PrefSubscriptionType != SubscriptionTypes.Disabled && !(Subscriptions.IsSubscribed(portalId, forumModuleId, forumId, topicId, SubscriptionTypes.Instant, aftContext.UserId)))
                {
                    new SubscriptionController().Subscription_Update(portalId, forumModuleId, forumId, topicId, (int)userProfile.PrefSubscriptionType, aftContext.UserId, aftContext.ForumUser.UserRoles);
                }

                if (isApproved)
                {
                    // Send User Notifications
                    Subscriptions.SendSubscriptions(portalId, forumModuleId, aftContext.ModuleSettings.ForumTabId, forumInfo, topicId, 0, ti.Content.AuthorId);

                    // Add Journal entry
                    var forumTabId = aftContext.ModuleSettings.ForumTabId;
                    var fullURL = new ControlUtils().BuildUrl(forumTabId, forumModuleId, forumInfo.ForumGroup.PrefixURL, forumInfo.PrefixURL, forumInfo.ForumGroupId, forumInfo.ForumID, topicId, ti.TopicUrl, -1, -1, string.Empty, 1, -1, forumInfo.SocialGroupId);
                    new Social().AddTopicToJournal(portalId, forumModuleId, forumId, topicId, ti.Author.AuthorId, fullURL, ti.Content.Subject, string.Empty, ti.Content.Body, forumInfo.ActiveSocialSecurityOption, forumInfo.Security.Read, forumInfo.SocialGroupId);
                }
                else
                {
                    // Send Mod Notifications
                    var mods = Utilities.GetListOfModerators(portalId, forumId);
                    var notificationType = NotificationsController.Instance.GetNotificationType("AF-ForumModeration");
                    var notifySubject = Utilities.GetSharedResource("NotificationSubjectTopic");
                    notifySubject = notifySubject.Replace("[DisplayName]", dnnUser.DisplayName);
                    notifySubject = notifySubject.Replace("[TopicSubject]", ti.Content.Subject);
                    var notifyBody = Utilities.GetSharedResource("NotificationBodyTopic");
                    notifyBody = notifyBody.Replace("[Post]", ti.Content.Body);
                    var notificationKey = string.Format("{0}:{1}:{2}:{3}:{4}", aftContext.ModuleSettings.ForumTabId, forumModuleId, forumId, topicId, 0);

                    var notification = new Notification
                    {
                        NotificationTypeID = notificationType.NotificationTypeId,
                        Subject = notifySubject,
                        Body = notifyBody,
                        IncludeDismissAction = false,
                        SenderUserID = dnnUser.UserID,
                        Context = notificationKey
                    };

                    NotificationsController.Instance.SendNotification(notification, portalId, null, mods);
                }

            }
            catch (Exception ex)
            {
                Services.Exceptions.Exceptions.LogException(ex);
            }


            var result = new XmlRpcStruct
            {
                {"result", true}, //"true" for success
               // {"result_text", "OK".ToBytes()}, 
                {"topic_id", ti.TopicId.ToString()},
            };

            if (!isApproved)
                result.Add("state", 1);

            return result;

        }
        public XmlRpcStruct Login(string login, string password)
        {
            var aftContext = ActiveForumsTapatalkModuleContext.Create(Context);

            if (aftContext == null || aftContext.Portal == null)
                throw new XmlRpcFaultException(100, "Invalid Context");

            var loginStatus = UserLoginStatus.LOGIN_FAILURE;

            Entities.Users.UserController.ValidateUser(aftContext.Portal.PortalID, login, password, string.Empty, aftContext.Portal.PortalName, Context.Request.UserHostAddress, ref loginStatus);

            var result = false;
            var resultText = string.Empty;

            switch (loginStatus)
            {
                case UserLoginStatus.LOGIN_SUCCESS:
                case UserLoginStatus.LOGIN_SUPERUSER:
                    result = true;
                    break;

                case UserLoginStatus.LOGIN_FAILURE:
                    resultText = "Invalid Login/Password Combination";
                    break;

                case UserLoginStatus.LOGIN_USERNOTAPPROVED:
                    resultText = "User Not Approved";
                    break;

                case UserLoginStatus.LOGIN_USERLOCKEDOUT:
                    resultText = "User Temporarily Locked Out";
                    break;

                default:
                    resultText = "Unknown Login Error";
                    break;
            }

            User forumUser = null;

            if (result)
            {
                // Get the User
                var userInfo = Entities.Users.UserController.GetUserByName(aftContext.Module.PortalID, login);

                if (userInfo == null)
                {
                    result = false;
                    resultText = "Unknown Login Error";
                }
                else
                {
                    // Set Login Cookie
                    var expiration = DateTime.Now.Add(FormsAuthentication.Timeout);

                    var ticket = new FormsAuthenticationTicket(1, login, DateTime.Now, expiration, false, userInfo.UserID.ToString());
                    var authCookie = new HttpCookie(aftContext.AuthCookieName, FormsAuthentication.Encrypt(ticket))
                    {
                        Domain = FormsAuthentication.CookieDomain,
                        Path = FormsAuthentication.FormsCookiePath,
                    };


                    Context.Response.SetCookie(authCookie);

                    forumUser = new ActiveForums.UserController().GetUser(aftContext.Module.PortalID, aftContext.ModuleSettings.ForumModuleId, userInfo.UserID);
                }
            }

            Context.Response.AddHeader("Mobiquo_is_login", result ? "true" : "false");



            var rpcstruct = new XmlRpcStruct
                                {
                                    {"result", result },
                                    {"result_text", resultText.ToBytes()}, 
                                    {"can_upload_avatar", false},
                                    {"can_pm", false}
                                };

            if (result && forumUser != null)
            {
                rpcstruct.Add("user_id", forumUser.UserId.ToString());
                rpcstruct.Add("username", forumUser.UserName.ToBytes());
                rpcstruct.Add("email", forumUser.Email.ToBytes());
                rpcstruct.Add("usergroup_id", new string[] { });
                rpcstruct.Add("post_count", forumUser.PostCount);
                rpcstruct.Add("icon_url", GetAvatarUrl(forumUser.UserId));

            }


            return rpcstruct;

        }
        public XmlRpcStruct GetConfig()
        {
            var aftContext = ActiveForumsTapatalkModuleContext.Create(Context);

            if (aftContext == null || aftContext.Module == null)
                throw new XmlRpcFaultException(100, "Invalid Context");

            Context.Response.AddHeader("Mobiquo_is_login", aftContext.UserId > 0 ? "true" : "false");

            var rpcstruct = new XmlRpcStruct
            {
                {"sys_version", "5.0.4"},
                {"version", "dev"}, 
                {"is_open", aftContext.ModuleSettings.IsOpen}, 
                {"api_level", "4"},
                {"guest_okay", aftContext.ModuleSettings.AllowAnonymous},
                {"disable_bbcode", "0"},
                {"min_search_length", "3"},
                {"reg_url", "register.aspx"},
                {"charset", "UTF-8"},
                {"subscribe_forum", "1"},
                {"multi_quote", "1"},
                {"goto_unread", "1"},
                {"goto_post", "1"},
                {"announcement", "1"},
                {"no_refresh_on_post", "1"},
                {"subscribe_load", "1"},
                {"user_id", "1"},
                {"avatar", "0"},
                {"disable_subscribe_forum", "0"},
                {"get_latest_topic", "1"},
                {"mark_read", "1"},
                {"mark_forum", "1"},
                {"get_forum_status", "1"},
                {"hide_forum_id", ""},
                {"mark_topic_read", "1"},
                {"get_topic_status", "1"},
                {"get_participated_forum", "1"},
                {"get_forum", "1"},
                {"guest_search", aftContext.ModuleSettings.SearchPermission == ActiveForumsTapatalkModuleSettings.SearchPermissions.Everyone ? "1" : "0"},
                {"advanced_search", "0"},
                {"searchid", "1"},
                {"can_unread", "1"},
                /* Not Yet Implemented */
                
                {"conversation", "0"},
                {"inbox_stat", "0"},
                {"push", "0"},   
                {"allow_moderate", "0"},
                {"report_post", "0"},
                {"report_pm", "0"},
                {"get_id_by_url", "0"},
                {"delete_reason", "0"},
                {"mod_approve", "0"},
                {"mod_delete", "0"},
                {"mod_report", "0"},
                {"pm_load", "0"},              
                {"mass_subscribe", "0"},
                {"emoji", "0"},
                {"get_smiles", "0"},
                {"get_online_users", "0"},
                {"search_user", "0"},
                {"ignore_user", "0"},
                {"user_recommended", "0"},
                {"mark_pm_unread", "0"},
                {"get_activity", "0"},
                {"get_alert", "0"},
                {"advanced_delete", "0"},
                {"default_smiles", "0"}
            };

            return rpcstruct;

        }
 Object ParseHashtable(
     XmlNode node,
     Type valueType,
     ParseStack parseStack,
     MappingAction mappingAction)
 {
     XmlRpcStruct retObj = new XmlRpcStruct();
       parseStack.Push("struct mapped to XmlRpcStruct");
       try
       {
     XmlNode[] members = SelectNodes(node, "member");
     foreach (XmlNode member in members)
     {
       if (member.Name != "member")
     continue;
       XmlNode nameNode;
       bool dupName;
       XmlNode valueNode;
       bool dupValue;
       SelectTwoNodes(member, "name", out nameNode, out dupName, "value",
     out valueNode, out dupValue);
       if (nameNode == null || nameNode.FirstChild == null)
     throw new XmlRpcInvalidXmlRpcException(parseStack.ParseType
       + " contains a member with missing name"
       + " " + StackDump(parseStack));
       if (dupName)
     throw new XmlRpcInvalidXmlRpcException(parseStack.ParseType
       + " contains member with more than one name element"
       + " " + StackDump(parseStack));
       string rpcName = nameNode.FirstChild.Value;
       if (valueNode == null)
     throw new XmlRpcInvalidXmlRpcException(parseStack.ParseType
       + " contains struct member " + rpcName + " with missing value "
       + " " + StackDump(parseStack));
       if (dupValue)
     throw new XmlRpcInvalidXmlRpcException(parseStack.ParseType
       + " contains member with more than one value element"
       + " " + StackDump(parseStack));
       if (retObj.Contains(rpcName))
       {
     if (!IgnoreDuplicateMembers)
       throw new XmlRpcInvalidXmlRpcException(parseStack.ParseType
         + " contains struct value with duplicate member "
         + nameNode.FirstChild.Value
         + " " + StackDump(parseStack));
     else
       continue;
       }
       object valObj;
       parseStack.Push(String.Format("member {0}", rpcName));
       try
       {
     XmlNode vvNode = SelectValueNode(valueNode);
     valObj = ParseValue(vvNode, null, parseStack,
       mappingAction);
       }
       finally
       {
     parseStack.Pop();
       }
       retObj.Add(rpcName, valObj);
     }
       }
       finally
       {
     parseStack.Pop();
       }
       return retObj;
 }