Click here to Skip to main content
15,896,557 members
Articles / Mobile Apps / Windows Mobile

Audio Book Player

Rate me:
Please Sign up or sign in to vote.
4.86/5 (36 votes)
11 Jun 2009CPOL6 min read 198.8K   3.5K   84  
Audio player designed specifically for listening to audio books
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.Xml;
using System.Collections;

class cXMLPersistancy : cBasePersistancy
{
    private String APP_NAME = "";
    private String ROOT_PATH = "";
    private String VOLATILE_PATH = "";
    private XmlDocument fDoc = null;
    private XmlDocument fVolatile = null;
    private XmlElement fBooks = null;
    private XmlElement fBookshelves = null;
    private const String BOOKS_ELEMENT_NAME = "BOOKS";
    private const String BOOKSHELVES_ELEMENT_NAME = "BOOKSHELVES";
    private const String BOOK_ELEMENT_NAME = "BOOK";
    private const String BOOKSHELF_ELEMENT_NAME = "BOOKSHELF";
    private const String FILES_ELEMENT_NAME = "FILES";
    private const String NAME_ATTRIBUTE_NAME = "NAME";
    private const String SKIN_ATTRIBUTE_NAME = "SKIN";
    private const String BOOK_ATTRIBUTE_PREFIX = "BOOK-";
    private const String FILE_ATTRIBUTE_PREFIX = "FILE-";
    private String[] BOOK_ATTRIBUTE_NAMES = {"BOOKMARKENTRY", "BOOKMARKLOCATION",
                                            "VOLUME", "SHUFFLE"};
    private String[] BOOK_ATTRIBUTE_DEFAULTS = { "0", "0", "40", "0" };

    public cXMLPersistancy(String assembly)
    {
        APP_NAME = assembly;
        ROOT_PATH = GetLargestStorageCard();
        if (ROOT_PATH.Length == 0)
            throw new Exception("No Storage card Found");
        VOLATILE_PATH = ROOT_PATH + "\\_" + assembly + "_VOLATILE_.XML";
        ROOT_PATH += "\\_" + assembly + "_.XML";
        fDoc = new XmlDocument();
        if (File.Exists(ROOT_PATH))
            fDoc.Load(ROOT_PATH);
        else
        {
            fDoc.AppendChild(fDoc.CreateElement(assembly));
            fDoc.DocumentElement.AppendChild(fDoc.CreateElement(BOOKS_ELEMENT_NAME));
            fDoc.DocumentElement.AppendChild(fDoc.CreateElement(BOOKSHELVES_ELEMENT_NAME));
            fDoc.DocumentElement.SetAttribute(SKIN_ATTRIBUTE_NAME, "");
            Save();
        }
        XmlElement node = (XmlElement)fDoc.DocumentElement.FirstChild;
        while (node != null)
        {
            if (node.Name == BOOKS_ELEMENT_NAME)
                fBooks = node;
            if (node.Name == BOOKSHELVES_ELEMENT_NAME)
                fBookshelves = node;
            node = (XmlElement)node.NextSibling;
        }
        if ((fBooks == null) || (fBookshelves == null))
            throw new Exception("Invalid XML File");
        if (File.Exists(VOLATILE_PATH))
        {
            fVolatile = new XmlDocument();
            fVolatile.Load(VOLATILE_PATH);
        }
    }
    private bool LoadVolatile()
    {
        try
        {
            if (ActiveBookName == "") return false;
            XmlElement dNode = GetBookElement(ActiveBookName);
            if (dNode == null) return false;
            XmlElement vNode = fVolatile.DocumentElement;
            for (int i = 0; i < BOOK_ATTRIBUTE_NAMES.Length; i++)
                dNode.SetAttribute(BOOK_ATTRIBUTE_NAMES[i],
                vNode.GetAttribute(BOOK_ATTRIBUTE_NAMES[i]));
            return Save();
        }
        catch { }
        return false;
    }
    private bool CreateVolatile(String abn)
    {
        try
        {
            if (abn == "") return false;
            XmlElement dNode = GetBookElement(abn);
            if (dNode == null) return false;
            fVolatile = new XmlDocument();
            XmlElement vNode = (XmlElement)fVolatile.AppendChild(fVolatile.CreateElement(APP_NAME));
            vNode.SetAttribute(NAME_ATTRIBUTE_NAME, abn);
            for (int i = 0; i < BOOK_ATTRIBUTE_NAMES.Length; i++)
                vNode.SetAttribute(BOOK_ATTRIBUTE_NAMES[i],
                dNode.GetAttribute(BOOK_ATTRIBUTE_NAMES[i]));
            fVolatile.Save(VOLATILE_PATH);
            return true;
        }
        catch { }
        return false;
    }
    private int GetBookProperty(eBookProperty prop) // volatile
    {
        try
        {
            if (ActiveBookName == "") return 0;
            XmlElement node = (XmlElement)fVolatile.DocumentElement;
            if (node == null) return 0;
            return Convert.ToInt32(node.GetAttribute(BOOK_ATTRIBUTE_NAMES[(int)prop]));
        }
        catch { }
        return 0;
    }
    private bool SetBookProperty(eBookProperty prop, int value) //volatile
    {
        try
        {
            if (ActiveBookName == "") return false;
            XmlElement node = (XmlElement)fVolatile.DocumentElement;
            if (node == null) return false;
            node.SetAttribute(BOOK_ATTRIBUTE_NAMES[(int)prop], value.ToString());
            fVolatile.Save(VOLATILE_PATH);
            return true;
        }
        catch { }
        return false;
    }
    private bool Save()
    {
        try
        {
            fDoc.Save(ROOT_PATH);
            return true;
        }
        catch { };
        return false;

    }
    public override String ActiveBookName
    {
        get
        {
            if (fVolatile == null) return "";
            return fVolatile.DocumentElement.GetAttribute(NAME_ATTRIBUTE_NAME);
        }
        set
        {
            LoadVolatile();
            if ((value == null) || (value == ""))
            {
                fVolatile = null;
                File.Delete(VOLATILE_PATH);
            }
            else
                CreateVolatile(value);
        }
    }
    public override String Skin
    {
        get
        {
            return fDoc.DocumentElement.GetAttribute(SKIN_ATTRIBUTE_NAME);
        }
        set
        {
            fDoc.DocumentElement.SetAttribute(SKIN_ATTRIBUTE_NAME, value);
            Save();
        }
    }
    public override String[] Books
    {
        get
        {
            String[] bks = GetNameList(fBooks.GetElementsByTagName(BOOK_ELEMENT_NAME));
            return bks;
        }
    }
    public override String[] Bookshelves
    {
        get
        {
            String[] bks = GetNameList(fBookshelves.GetElementsByTagName(BOOKSHELF_ELEMENT_NAME));
            return bks;
        }
    }
    private String[] GetNameList(XmlNodeList list)
    {
        try
        {
            String[] bks = new String[list.Count];
            for (int i = 0; i < list.Count; i++)
                bks[i] = ((XmlElement)list[i]).GetAttribute(NAME_ATTRIBUTE_NAME);
            Array.Sort(bks);
            return bks;
        }
        catch { }
        return new String[0];
    }
    private XmlElement GetBookElement(String name)
    {
        return GetElement(fBooks.GetElementsByTagName(BOOK_ELEMENT_NAME), 
            (name == "")? ActiveBookName: name);
    }
    private XmlElement GetBookshelfElement(String name)
    {
        if(name == "") return fBookshelves;
        return GetElement(fBookshelves.GetElementsByTagName(BOOKSHELF_ELEMENT_NAME), name);
    }
    private XmlElement GetElement(XmlNodeList list, String name)
    {
        try
        {
            foreach (XmlElement node in list)
                if (node.GetAttribute(NAME_ATTRIBUTE_NAME) == name)
                    return node;
        }
        catch { }
        return null;
    }
    public override int GetBookProperty(eBookProperty prop, String book)
    {
        if ((book == "") && (ActiveBookName == "")) return 0;
        if ((book == "") || (book == ActiveBookName))
            return GetBookProperty(prop);
        XmlElement node = GetBookElement(book);
        if (node == null) return 0;
        return Convert.ToInt32(node.GetAttribute(BOOK_ATTRIBUTE_NAMES[(int)prop]));
    }
    public override bool SetBookProperty(eBookProperty prop, int value, String book)
    {
        if ((book == "") && (ActiveBookName == "")) return false;
        if ((book == "") || (book == ActiveBookName))
            return SetBookProperty(prop, value);
        XmlElement node = GetBookElement(book);
        if (node == null) return false;
        node.SetAttribute(BOOK_ATTRIBUTE_NAMES[(int)prop], value.ToString());
        return Save();
    }
    public override String[] GetBookshelfBooks(String bookshelf)
    {
        XmlElement bs = (XmlElement)GetBookshelfElement(bookshelf);
        if(bs == null) return new String[0];
        XmlAttributeCollection list = bs.Attributes;
        ArrayList books = new ArrayList();
        for (int i = 0; i < list.Count; i++)
            if(((XmlAttribute)(list.Item(i))).Name != NAME_ATTRIBUTE_NAME)
                books.Add(((XmlAttribute)(list.Item(i))).Value);
        String[] bks = (String[])books.ToArray(typeof(String));
        Array.Sort(bks);
        return bks;
    }
    private String GetAttributeNameOf(XmlElement node, String name)
    {
        foreach (XmlAttribute attr in node.Attributes)
            if (attr.Name != NAME_ATTRIBUTE_NAME)
                if (attr.Value == name)
                    return attr.Name;
        return "";
    }
    public override String GetBooksBookshelf(String book)
    {
        if ((book == "") && (ActiveBookName == "")) return "";
        String bk = (book == "") ? ActiveBookName : book;
        if (GetAttributeNameOf(fBookshelves, bk) != "") return "";
        XmlElement bs = (XmlElement)fBookshelves.FirstChild;
        while (bs != null)
        {
            if (GetAttributeNameOf(bs, bk) != "") 
                return bs.GetAttribute(NAME_ATTRIBUTE_NAME);
            bs = (XmlElement)bs.NextSibling;
        }
        return "";
    }
    public override bool NewBookshelf(String bookshelf)
    {
        XmlElement bs = (XmlElement)fBookshelves.AppendChild(fDoc.CreateElement(BOOKSHELF_ELEMENT_NAME));
        bs.SetAttribute(NAME_ATTRIBUTE_NAME, bookshelf);
        return Save();
    }
    public override bool DeleteBookshelf(String bookshelf)
    {
        if (bookshelf == "") return false;
        XmlElement item = GetBookshelfElement(bookshelf);
        if(item == null) return false;
        ArrayList books = new ArrayList();
        books.AddRange(GetBookshelfBooks(""));
        books.AddRange(GetBookshelfBooks(bookshelf));
        fBookshelves.RemoveAllAttributes();
        int len = books.Count.ToString().Length;
        int n = 1;
        foreach (String book in books)
        {
            String name = n.ToString();
            while (name.Length < len)
                name = "0" + name;
            fBookshelves.SetAttribute(BOOK_ATTRIBUTE_PREFIX + name, book);
            n++;
        }
        fBookshelves.RemoveChild(item);
        return Save();
    }
    public override bool SetBooksBookshelf(String book, String newBookshelf)
    {
        String obs = GetBooksBookshelf(book);
        if (obs == "")
        {
            String attr = GetAttributeNameOf(fBookshelves, book);
            if(attr != "")
                fBookshelves.RemoveAttribute(attr);
        }
        else
        {
            XmlElement obse = GetBookshelfElement(obs);
            String attr = GetAttributeNameOf(obse, book);
            if(attr != "")
                obse.RemoveAttribute(attr);
        }
        XmlElement bse = GetBookshelfElement(newBookshelf);
        ArrayList books = new ArrayList();
        books.AddRange(GetBookshelfBooks(newBookshelf));
        books.Add(book);
        bse.RemoveAllAttributes();
        if (newBookshelf != "")
            bse.SetAttribute(NAME_ATTRIBUTE_NAME, newBookshelf);
        int len = books.Count.ToString().Length;
        int n = 1;
        foreach (String bk in books)
        {
            String name = n.ToString();
            while (name.Length < len)
                name = "0" + name;
            bse.SetAttribute(BOOK_ATTRIBUTE_PREFIX + name, bk);
            n++;
        }
        return Save();
    }
    public override bool NewBook(String book, String bookshelf)
    {
        XmlElement bk = (XmlElement)fBooks.AppendChild(fDoc.CreateElement(BOOK_ELEMENT_NAME));
        bk.SetAttribute(NAME_ATTRIBUTE_NAME, book);
        SetBooksBookshelf(book, bookshelf);
        bk.AppendChild(fDoc.CreateElement(FILES_ELEMENT_NAME));
        for (int i = 0; i < BOOK_ATTRIBUTE_NAMES.Length; i++)
            bk.SetAttribute(BOOK_ATTRIBUTE_NAMES[i], BOOK_ATTRIBUTE_DEFAULTS[i]);
        return Save();
    }
    public override int GetBookFileCount(String book)
    {
        XmlElement node = GetBookElement(book);
        if (node == null) return 0;
        node = (XmlElement)node.SelectSingleNode(FILES_ELEMENT_NAME);
        if (node == null) return 0;
        return node.Attributes.Count;
    }
    public override String[] GetBookFiles(String book)
    {
        XmlElement node = GetBookElement(book);
        if (node == null) return new String[0];
        node = (XmlElement)node.SelectSingleNode(FILES_ELEMENT_NAME);
        if (node == null) return new String[0];
        XmlAttributeCollection attr = node.Attributes;
        String[] files = new String[attr.Count];
        for(int i=0; i<attr.Count; i++)
            files[i] = attr[i].Name;
        Array.Sort(files);
        for(int i=0; i<attr.Count; i++)
            files[i] = node.GetAttribute(files[i]); ;
        return files;
    }
    public override bool SetBookFiles(String[] newFiles, String book)
    {
        XmlElement node = GetBookElement(book);
        if (node == null) return false;
        node = (XmlElement)node.SelectSingleNode(FILES_ELEMENT_NAME);
        String[] oldFiles = GetBookFiles(book);
        node.RemoveAllAttributes();
        int len = (oldFiles.GetLength(0) + newFiles.GetLength(0)).ToString().Length;
        int n = 1;
        foreach (String file in oldFiles)
        {
            String name = n.ToString();
            while (name.Length < len)
                name = "0" + name;
            node.SetAttribute(FILE_ATTRIBUTE_PREFIX + name, file);
            n++;
        }
        foreach (String file in newFiles)
        {
            String name = n.ToString();
            while (name.Length < len)
                name = "0" + name;
            node.SetAttribute(FILE_ATTRIBUTE_PREFIX + name, file);
            n++;
        }
        return Save();
    }
    public override bool DeleteBookFile(int ix, String book)
    {
        XmlElement node = GetBookElement(book);
        if (node == null) return false;
        node = (XmlElement)node.SelectSingleNode(FILES_ELEMENT_NAME);
        node.RemoveAttributeAt(ix);
        return Save();
    }
    public override bool DeleteBookFiles(String book)
    {
        XmlElement node = GetBookElement(book);
        if (node == null) return false;
        node = (XmlElement)node.SelectSingleNode(FILES_ELEMENT_NAME);
        node.RemoveAllAttributes();
        return Save();
    }
    public override bool RenameBookShelf(String newName, String bookshelf)
    {
        if(bookshelf == "") return false;
        XmlElement node = GetBookshelfElement(bookshelf);
        if (node == null) return false;
        node.SetAttribute(NAME_ATTRIBUTE_NAME, newName);
        return Save();
    }
    public override bool RenameBook(String newName, String book)
    {
        XmlElement bk = GetBookElement(book);
        XmlElement bs = GetBookshelfElement(GetBooksBookshelf(book));
        if ((bk == null) || (bs == null)) return false;
        bk.SetAttribute(NAME_ATTRIBUTE_NAME, newName);
        String attr = GetAttributeNameOf(bs, book);
        bs.SetAttribute(attr, newName);
        if (ActiveBookName == book)
            ActiveBookName = newName;
        return Save();
    }
    public override bool DeleteBook(String book)
    {
        XmlElement bk = GetBookElement(book);
        if (bk == null) return false;
        XmlElement bs = GetBookshelfElement(GetBooksBookshelf(book));
        if (bs == null) return false;
        String attr = GetAttributeNameOf(bs, book);
        bs.RemoveAttribute(attr);
        if (ActiveBookName == book)
            ActiveBookName = "";
        fBooks.RemoveChild(bk);
        return Save();
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Israel Israel
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions