private static string GetContainerTcmId(MappingInfo mapping, TridionRole tridionRole, ProjectFileInfo file)
 {
     ProjectFolderInfo folder = file.GetTopFolder();
     return GetContainerTcmId(mapping, tridionRole, folder, file.Path);
 }
        public static void SyncRazorLayoutTbb(MappingInfo mapping, string tcmContainer, ProjectFileInfo file, ProjectFolderRole role, string serverTimeZoneId)
        {
            string path = file.FullPath;
            if (String.IsNullOrEmpty(path))
                return;

            if (!File.Exists(path))
            {
                //remove non-existing file from mapping
                foreach (ProjectFolderInfo folder in mapping.ProjectFolders)
                {
                    Service.DeleteFileFromMapping(folder, path);
                }
                return;
            }

            IncludeProjectItem(path);

            string title;
            if (String.IsNullOrEmpty(file.Title))
            {
                title = Path.GetFileNameWithoutExtension(path);
                file.Title = title;
            }
            else
            {
                title = file.Title;
            }

            string id;
            if (String.IsNullOrEmpty(file.TcmId))
            {
                id = GetItemTcmId(mapping, tcmContainer, title);
                file.TcmId = id;
            }
            else
            {
                id = file.TcmId;
            }

            string fileContent = TransformRazor2Mediator(File.ReadAllText(path));

            bool updated = false;

            if (String.IsNullOrEmpty(id))
            {
                TridionDestinationDialogWindow dialog = new TridionDestinationDialogWindow();
                dialog.Mapping = mapping;
                dialog.FilterItemTcmId = tcmContainer;
                dialog.PublicationTcmId = GetPublicationTcmId(tcmContainer);
                dialog.LayoutTitle = title;
                dialog.TemplateTitle = String.IsNullOrEmpty(file.TemplateTitle) ? title : file.TemplateTitle;
                bool res = dialog.ShowDialog() == true;
                if (res)
                {
                    file.Title = dialog.LayoutTitle;
                    file.TemplateTitle = dialog.TemplateTitle;
                    tcmContainer = GetBluePrintItemTcmId(tcmContainer, dialog.PublicationTcmId);
                    string stackTraceMessage;
                    updated = SaveRazorLayoutTbb(mapping, file.Title, fileContent, tcmContainer, out stackTraceMessage);
                    if (updated)
                    {
                        id = GetItemTcmId(mapping, tcmContainer, file.Title);
                        if (String.IsNullOrEmpty(id))
                        {
                            WriteErrorLog(file.Path + " - Item is broken after updating");
                            return;
                        }
                        file.TcmId = id;
                    }
                    else
                    {
                        WriteErrorLog(file.Path + " - Creating failed", stackTraceMessage);
                        return;
                    }
                }
            }

            TemplateBuildingBlockData item = ReadItem(mapping, id) as TemplateBuildingBlockData;

            if (item == null || item.VersionInfo.RevisionDate == null)
            {
                WriteErrorLog(String.Format("Item {0} does not exist", id));
                return;
            }

            FileInfo fi = new FileInfo(path);
            DateTime fileDate = fi.LastWriteTime;
            DateTime tridionDate = (DateTime) item.VersionInfo.RevisionDate;
            DateTime tridionLocalDate = tridionDate.GetLocalTime(serverTimeZoneId);

            if (updated)
            {
                File.SetAttributes(path, FileAttributes.Normal);
                File.SetLastWriteTime(path, tridionLocalDate);
                WriteSuccessLog(file.Path + " - Saved to Tridion CM successfully");
                return;
            }

            if (fileDate == tridionLocalDate)
                return;

            string tridionContent = item.Content;
            file.Title = item.Title;

            if (Equals(fileContent, tridionContent))
            {
                File.SetAttributes(path, FileAttributes.Normal);
                File.SetLastWriteTime(path, tridionLocalDate);
                WriteSuccessLog(file.Path + " - Date of project item is updated to " + tridionLocalDate);
            }
            else
            {
                string user = item.VersionInfo is FullVersionInfo && ((FullVersionInfo)item.VersionInfo).Revisor != null ? ((FullVersionInfo)item.VersionInfo).Revisor.Title : "Unknown";

                DiffDialogWindow dialog = new DiffDialogWindow();
                if (fileDate > tridionLocalDate)
                {
                    dialog.StartItemInfo = String.Format("Tridion Item: {0} ({1}), {2}, {3}", item.Title, item.Id, tridionLocalDate, user);
                    dialog.EndItemInfo = String.Format("VS File: {0}, {1}", Path.GetFileName(path), fileDate);
                    dialog.StartItemText = tridionContent;
                    dialog.EndItemText = fileContent;
                    dialog.SyncState = SyncState.VS2Tridion;
                    dialog.Tridion2VSEnabled = true;
                    dialog.VS2TridionEnabled = !IsCheckedOut(mapping, item.Id);
                }
                else
                {
                    dialog.StartItemInfo = String.Format("VS File: {0}, {1}", Path.GetFileName(path), fileDate);
                    dialog.EndItemInfo = String.Format("Tridion Item: {0} ({1}), {2}, {3}", item.Title, item.Id, tridionLocalDate, user);
                    dialog.StartItemText = fileContent;
                    dialog.EndItemText = tridionContent;
                    dialog.SyncState = SyncState.Tridion2VS;
                    dialog.Tridion2VSEnabled = true;
                    dialog.VS2TridionEnabled = true;
                }

                bool res = dialog.ShowDialog() == true;
                if (res)
                {
                    if (dialog.SyncState == SyncState.VS2Tridion)
                    {
                        string stackTraceMessage;
                        updated = SaveRazorLayoutTbb(mapping, id, fileContent, out stackTraceMessage);
                        if (updated)
                        {
                            item = ReadItem(mapping, id) as TemplateBuildingBlockData;
                            if (item == null || item.VersionInfo.RevisionDate == null)
                            {
                                WriteErrorLog(String.Format("Item {0} does not exist", id));
                            }
                            else
                            {
                                tridionDate = (DateTime)item.VersionInfo.RevisionDate;
                                tridionLocalDate = tridionDate.GetLocalTime(serverTimeZoneId);
                                File.SetAttributes(path, FileAttributes.Normal);
                                File.SetLastWriteTime(path, tridionLocalDate);
                                WriteSuccessLog(file.Path + " - Saved to Tridion CM successfully");
                            }
                        }
                        else
                        {
                            WriteErrorLog(file.Path + " - Updating failed", stackTraceMessage);
                        }
                    }
                    else if (dialog.SyncState == SyncState.Tridion2VS)
                    {
                        SaveVSItem(path, tridionContent);
                        File.SetAttributes(path, FileAttributes.Normal);
                        File.SetLastWriteTime(path, tridionLocalDate);
                        WriteSuccessLog(file.Path + " - Saved to Visual Studio successfully");
                    }
                }
            }
        }
        public static void SyncMultimedia(MappingInfo mapping, ProjectFileInfo file, string tcmContainer, string serverTimeZoneId)
        {
            string path = file.FullPath;

            if (!File.Exists(path))
            {
                //remove non-existing file from mapping
                foreach (ProjectFolderInfo folder in mapping.ProjectFolders)
                {
                    Service.DeleteFileFromMapping(folder, path);
                }
                return;
            }

            IncludeProjectItem(path);

            string title;
            if (String.IsNullOrEmpty(file.Title))
            {
                title = Path.GetFileNameWithoutExtension(path);
                file.Title = title;
            }
            else
            {
                title = file.Title;
            }

            string id;
            if (String.IsNullOrEmpty(file.TcmId))
            {
                id = GetItemTcmId(mapping, tcmContainer, title);
                if (String.IsNullOrEmpty(id))
                    id = GetItemTcmId(mapping, tcmContainer, Path.GetFileNameWithoutExtension(path));
                if (String.IsNullOrEmpty(id))
                    id = GetItemTcmId(mapping, tcmContainer, Path.GetFileName(path));

                file.TcmId = id;
            }
            else
            {
                id = file.TcmId;
            }

            if (!File.Exists(path) && String.IsNullOrEmpty(id))
                return;

            bool updated = false;

            if (File.Exists(path) && String.IsNullOrEmpty(id))
            {
                TridionDestinationDialogWindow dialog = new TridionDestinationDialogWindow();
                dialog.Mapping = mapping;
                dialog.FilterItemTcmId = tcmContainer;
                dialog.PublicationTcmId = GetPublicationTcmId(tcmContainer);
                dialog.LayoutTitle = title;
                bool res = dialog.ShowDialog() == true;
                if (res)
                {
                    file.Title = dialog.LayoutTitle;
                    tcmContainer = GetBluePrintItemTcmId(tcmContainer, dialog.PublicationTcmId);
                    string stackTraceMessage;
                    updated = SaveMultimediaComponentFromBinary(mapping, path, file.Title, tcmContainer, out stackTraceMessage);
                    if (updated)
                    {
                        id = GetItemTcmId(mapping, tcmContainer, Path.GetFileName(path));
                        if (String.IsNullOrEmpty(id))
                            id = GetItemTcmId(mapping, tcmContainer, Path.GetFileNameWithoutExtension(path));

                        if (String.IsNullOrEmpty(id))
                        {
                            WriteErrorLog(file.Path + " - Item is broken after updating");
                            return;
                        }
                        file.TcmId = id;
                    }
                    else
                    {
                        WriteErrorLog(path + " - Creating failed", stackTraceMessage);
                        return;
                    }
                }
            }

            ComponentData item = ReadItem(mapping, id) as ComponentData;

            if (item == null || item.VersionInfo.RevisionDate == null)
            {
                WriteErrorLog(String.Format("Item {0} does not exist", id));
                return;
            }

            FileInfo fi = new FileInfo(path);
            DateTime fileDate = fi.LastWriteTime;
            DateTime tridionDate = (DateTime)item.VersionInfo.RevisionDate;
            DateTime tridionLocalDate = tridionDate.GetLocalTime(serverTimeZoneId);

            if (updated)
            {
                File.SetAttributes(path, FileAttributes.Normal);
                File.SetLastWriteTime(path, tridionLocalDate);
                WriteSuccessLog(path + " - Saved to Tridion CM successfully");
                return;
            }

            if (fileDate == tridionLocalDate)
            {
                return;
            }

            file.Title = item.Title;

            if (fi.Length == item.BinaryContent.FileSize)
            {
                File.SetAttributes(path, FileAttributes.Normal);
                File.SetLastWriteTime(path, tridionLocalDate);
                WriteSuccessLog(path + " - Saved to Tridion CM successfully");
            }
            else
            {
                BinaryDiffDialogWindow dialog = new BinaryDiffDialogWindow();
                if (fileDate > tridionLocalDate)
                {
                    dialog.StartItemInfo = String.Format("Tridion Item: {0} ({1}), {2}", item.Title, item.Id, tridionLocalDate);
                    dialog.EndItemInfo = String.Format("VS File: {0}, {1}", Path.GetFileName(path), fileDate);
                    dialog.SyncState = SyncState.VS2Tridion;
                    dialog.Tridion2VSEnabled = true;
                    dialog.VS2TridionEnabled = !IsCheckedOut(mapping, item.Id);
                }
                else
                {
                    dialog.StartItemInfo = String.Format("VS File: {0}, {1}", Path.GetFileName(path), fileDate);
                    dialog.EndItemInfo = String.Format("Tridion Item: {0} ({1}), {2}", item.Title, item.Id, tridionLocalDate);
                    dialog.SyncState = SyncState.Tridion2VS;
                    dialog.Tridion2VSEnabled = true;
                    dialog.VS2TridionEnabled = true;
                }

                bool res = dialog.ShowDialog() == true;
                if (res)
                {
                    if (dialog.SyncState == SyncState.VS2Tridion)
                    {
                        string stackTraceMessage;
                        updated = SaveMultimediaComponentFromBinary(mapping, id, path, out stackTraceMessage);
                        if (updated)
                        {
                            item = ReadItem(mapping, id) as ComponentData;
                            if (item == null || item.VersionInfo.RevisionDate == null)
                            {
                                WriteErrorLog(String.Format("Item {0} does not exist", id));
                            }
                            else
                            {
                                tridionDate = (DateTime)item.VersionInfo.RevisionDate;
                                tridionLocalDate = tridionDate.GetLocalTime(serverTimeZoneId);
                                File.SetAttributes(path, FileAttributes.Normal);
                                File.SetLastWriteTime(path, tridionLocalDate);
                                WriteSuccessLog(path + " - Saved to Tridion CM successfully");
                            }
                        }
                        else
                        {
                            WriteErrorLog(path + " - Updating failed", stackTraceMessage);
                        }
                    }
                    else if (dialog.SyncState == SyncState.Tridion2VS)
                    {
                        SaveVSBinaryItem(mapping, id, path);
                        File.SetAttributes(path, FileAttributes.Normal);
                        File.SetLastWriteTime(path, tridionLocalDate);
                        WriteSuccessLog(path + " - Saved to Visual Studio successfully");
                    }
                }
            }
        }
        public static void ProcessFile(MappingInfo mapping, ProjectFileInfo file)
        {
            if (file == null)
                return;

            ShowMessage(file.Path + "...");

            if (!file.IsChecked() && !String.IsNullOrEmpty(file.TcmId))
                return;

            if (file.Checked != true)
                return;

            ProjectFolderRole role = file.ProjectFolderRole();
            bool syncTemplate = file.IsSyncTemplate();
            string templateFormat = file.TemplateFormat();
            List<string> schemaNames = file.SchemaNames;

            string titleItem = String.IsNullOrEmpty(file.Title) ? Path.GetFileNameWithoutExtension(file.FullPath) : file.Title;

            string tcmItemContainer = String.Empty;
            string tcmItem = String.Empty;

            string titleTemplate = String.Empty;
            string tcmTemplateContainer = String.Empty;

            TridionRole tridionRole = TridionRole.Other;

            if (role == ProjectFolderRole.PageLayout)
            {
                tridionRole = TridionRole.PageLayoutContainer;

                tcmItemContainer = GetContainerTcmId(mapping, TridionRole.PageLayoutContainer, file);
                tcmItem = String.IsNullOrEmpty(file.TcmId) ? GetItemTcmId(mapping, tcmItemContainer, titleItem) : file.TcmId;

                titleTemplate = String.IsNullOrEmpty(file.TemplateTitle) ? Path.GetFileNameWithoutExtension(file.FullPath) : file.TemplateTitle;
                tcmTemplateContainer = GetContainerTcmId(mapping, TridionRole.PageTemplateContainer, file.Path);
            }

            if (role == ProjectFolderRole.ComponentLayout)
            {
                titleItem = String.IsNullOrEmpty(file.Title) ? Path.GetFileNameWithoutExtension(file.FullPath) : file.Title;

                tridionRole = TridionRole.ComponentLayoutContainer;

                tcmItemContainer = GetContainerTcmId(mapping, TridionRole.ComponentLayoutContainer, file);
                tcmItem = String.IsNullOrEmpty(file.TcmId) ? GetItemTcmId(mapping, tcmItemContainer, titleItem) : file.TcmId;

                titleTemplate = String.IsNullOrEmpty(file.TemplateTitle) ? Path.GetFileNameWithoutExtension(file.FullPath) : file.TemplateTitle;
                tcmTemplateContainer = GetContainerTcmId(mapping, TridionRole.ComponentTemplateContainer, file.Path);
            }

            if (role == ProjectFolderRole.Binary)
            {
                tridionRole = TridionRole.MultimediaComponentContainer;

                tcmItemContainer = GetContainerTcmId(mapping, TridionRole.MultimediaComponentContainer, file);

                tcmItem = file.TcmId;
                if (String.IsNullOrEmpty(tcmItem))
                    tcmItem = GetItemTcmId(mapping, tcmItemContainer, Path.GetFileName(file.Path));
                if (String.IsNullOrEmpty(tcmItem))
                    tcmItem = GetItemTcmId(mapping, tcmItemContainer, Path.GetFileNameWithoutExtension(file.Path));
            }

            if (tridionRole == TridionRole.Other)
            {
                WriteErrorLog(String.Format("Role for item \"{0}\" is not detected", titleItem));
                ShowMessage(String.Empty);
                return;
            }

            if (String.IsNullOrEmpty(tcmItemContainer))
            {
                WriteErrorLog(String.Format("Could not find Tridion mapping for role {0}", tridionRole));
                ShowMessage(String.Empty);
                return;
            }

            //save (back) to file object
            file.TcmId = tcmItem;
            file.Title = titleItem;
            file.TemplateTitle = titleTemplate;

            //create sub-folder if file is not direct descedent
            if (file.Parent.FullPath.Trim('\\') != file.GetTopFolder().FullPath.Trim('\\'))
            {
                //get low-level folder
                tcmItemContainer = CreateFolderChain(mapping, file.Parent.FullPath.Trim('\\').Replace(file.GetTopFolder().FullPath.Trim('\\'), "").Trim('\\'), tcmItemContainer);
            }

            if (role == ProjectFolderRole.Binary)
            {
                SyncMultimedia(mapping, file, tcmItemContainer, mapping.TimeZoneId);
            }
            else
            {
                SyncRazorLayoutTbb(mapping, tcmItemContainer, file, role, mapping.TimeZoneId);
            }

            if (syncTemplate)
            {
                tcmItem = file.TcmId;

                //take template name from gialog
                if (!String.IsNullOrEmpty(file.TemplateTitle))
                    titleTemplate = file.TemplateTitle;

                if (String.IsNullOrEmpty(titleTemplate))
                    titleTemplate = titleItem;

                if(!String.IsNullOrEmpty(tcmItem) && !String.IsNullOrEmpty(tcmTemplateContainer) && !ExistsItem(mapping, tcmTemplateContainer, titleTemplate))
                {
                    if (role == ProjectFolderRole.PageLayout)
                    {
                        string stackTraceMessage;
                        bool res = SavePageTemplate(mapping, titleTemplate, String.Format(templateFormat, tcmItem, titleItem), tcmTemplateContainer, "cshtml", out stackTraceMessage);
                        if (!res)
                        {
                            WriteErrorLog(titleTemplate + " - Saving failed", stackTraceMessage);
                        }
                    }
                    if (role == ProjectFolderRole.ComponentLayout)
                    {
                        string stackTraceMessage;
                        bool res = SaveComponentTemplate(mapping, titleTemplate, String.Format(templateFormat, tcmItem, titleItem), tcmTemplateContainer, "HTML Fragment", false, out stackTraceMessage, schemaNames == null ? null : schemaNames.ToArray());
                        if (!res)
                        {
                            WriteErrorLog(titleTemplate + " - Saving failed", stackTraceMessage);
                        }
                    }
                }
            }

            ShowMessage(String.Empty);
        }
        public static void AddChildItems(ProjectFolderInfo projectFolder, string rootPath)
        {
            if (projectFolder == null)
                return;

            if (String.IsNullOrEmpty(projectFolder.FullPath))
                return;

            if (!Directory.Exists(projectFolder.FullPath))
                Directory.CreateDirectory(projectFolder.FullPath);

            ProjectFolderInfo topFolder = projectFolder.GetTopFolder();
            ProjectFolderRole role = topFolder.ProjectFolderRole;
            string[] extensions = role == TridionVSRazorExtension.ProjectFolderRole.Binary ? Extensions.Keys.ToArray() : new[] { "*.cshtml" };
            string[] directories = Directory.GetDirectories(projectFolder.FullPath);
            string[] files = GetFiles(projectFolder.FullPath, extensions);

            if (directories.Length == 0 && files.Length == 0)
            {
                projectFolder.ChildItems = null;
                return;
            }

            List<ProjectItemInfo> newChildItems = new List<ProjectItemInfo>();

            foreach (string dir in directories)
            {
                ProjectFolderInfo childFolder = null;

                if (projectFolder.ChildItems != null)
                {
                    childFolder = projectFolder.ChildItems.FirstOrDefault(x => x.IsFolder && x.FullPath == dir) as ProjectFolderInfo;
                }

                if (childFolder == null)
                {
                    childFolder = new ProjectFolderInfo { RootPath = rootPath, Path = dir.Replace(rootPath, "").Trim('\\'), Checked = false };
                }

                childFolder.Parent = projectFolder;

                AddChildItems(childFolder, rootPath);

                newChildItems.Add(childFolder);
            }

            foreach (string file in files)
            {
                ProjectFileInfo childFile = null;

                if (projectFolder.ChildItems != null)
                {
                    childFile = projectFolder.ChildItems.FirstOrDefault(x => x.IsFile && x.FullPath == file) as ProjectFileInfo;
                }

                if (childFile == null)
                {
                    childFile = new ProjectFileInfo { RootPath = rootPath, Path = file.Replace(rootPath, "").Trim('\\'), Checked = false };
                }

                childFile.Parent = projectFolder;

                newChildItems.Add(childFile);
            }

            projectFolder.ChildItems = newChildItems.Count > 0 ? newChildItems : null;
        }
        public static ProjectFolderInfo GetRootTree(ProjectFolderInfo projectFolder, string fullPath)
        {
            if (projectFolder == null)
                return null;

            if (!Directory.Exists(fullPath))
                return null;

            if (!ExistFile(projectFolder, fullPath) && projectFolder.FullPath != fullPath)
                return null;

            if (projectFolder.FullPath == fullPath)
            {
                projectFolder.IsSelected = true;
                projectFolder.Expand();
                return projectFolder;
            }

            string rootPath = projectFolder.RootPath;

            ProjectFolderInfo parentFolder = new ProjectFolderInfo { RootPath = rootPath, Path = fullPath.Replace(rootPath, "").Trim('\\'), Checked = false };
            parentFolder.ChildItems = new List<ProjectItemInfo>();

            foreach (string childFolderPath in Directory.GetDirectories(fullPath))
            {
                ProjectFolderInfo childFolder = GetRootTree(projectFolder, childFolderPath);
                if (childFolder != null)
                {
                    childFolder.Parent = parentFolder;
                    parentFolder.ChildItems.Add(childFolder);
                }
            }

            foreach (string childFilePath in GetFiles(fullPath, projectFolder.ProjectFolderRole == TridionVSRazorExtension.ProjectFolderRole.Binary ? Extensions.Keys.ToArray() : new[] { "*.cshtml" }))
            {
                ProjectFileInfo childFile = new ProjectFileInfo { RootPath = rootPath, Path = childFilePath.Replace(rootPath, "").Trim('\\'), Checked = false };
                childFile.Parent = parentFolder;
                parentFolder.ChildItems.Add(childFile);
            }

            if (parentFolder.ChildItems.Count == 0)
                parentFolder.ChildItems = null;

            return parentFolder;
        }