1 /*
2  * Copyright (C) 2018-2020 Rerrah
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use,
8  * copy, modify, merge, publish, distribute, sublicense, and/or sell
9  * copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following
11  * conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23  * OTHER DEALINGS IN THE SOFTWARE.
24  */
25 
26 #pragma once
27 
28 #include <vector>
29 #include <unordered_set>
30 #include <string>
31 #include <unordered_map>
32 #include "track.hpp"
33 #include "misc.hpp"
34 
35 struct SongStyle;
36 struct Bookmark;
37 
38 class Song
39 {
40 public:
41 	Song(int number, SongType songType = SongType::Standard, std::string title = u8"", bool isUsedTempo = true,
42 		 int tempo = 150, int groove = 0, int speed = 6, size_t defaultPatternSize = 64);
43 
44 	void setNumber(int n);
45 	int getNumber() const;
46 	void setTitle(std::string title);
47 	std::string getTitle() const;
48 	void setTempo(int tempo);
49 	int getTempo() const;
50 	void setGroove(int groove);
51 	int getGroove() const;
52 	void toggleTempoOrGroove(bool isUsedTempo);
53 	bool isUsedTempo() const;
54 	void setSpeed(int speed);
55 	int getSpeed() const;
56 	void setDefaultPatternSize(size_t size);
57 	size_t getDefaultPatternSize() const;
58 	size_t getPatternSizeFromOrderNumber(int order);
59 
60 	SongStyle getStyle() const;
61 	std::vector<TrackAttribute> getTrackAttributes() const;
62 	Track& getTrack(int num);
63 	void changeType(SongType type);
64 
65 	std::vector<OrderData> getOrderData(int order);
66 	size_t getOrderSize() const;
67 	bool canAddNewOrder() const;
68 	void insertOrderBelow(int order);
69 	void deleteOrder(int order);
70 	void swapOrder(int a, int b);
71 
72 	std::unordered_set<int> getRegisteredInstruments() const;
73 
74 	void clearUnusedPatterns();
75 	void replaceDuplicateInstrumentsInPatterns(std::unordered_map<int, int> map);
76 
77 	int addBookmark(std::string name, int order, int step);
78 	void changeBookmark(int i, std::string name, int order, int step);
79 	void removeBookmark(int i);
80 	void clearBookmark();
81 	void swapBookmarks(int a, int b);
82 	void sortBookmarkByPosition();
83 	void sortBookmarkByName();
84 	Bookmark getBookmark(int i) const;
85 	std::vector<int> findBookmarks(int order, int step) const;
86 	Bookmark getPreviousBookmark(int order, int step);
87 	Bookmark getNextBookmark(int order, int step);
88 	size_t getBookmarkSize() const;
89 
90 	void transpose(int seminotes, std::vector<int> excludeInsts);
91 	void swapTracks(int track1, int track2);
92 
93 private:
94 	int num_;
95 	SongType type_;
96 	std::string title_;
97 	bool isUsedTempo_;
98 	int tempo_;
99 	int groove_;
100 	int speed_;
101 	size_t defPtnSize_;
102 
103 	std::vector<Track> tracks_;
104 	std::vector<Bookmark> bms_;
105 
106 	std::vector<Bookmark> getSortedBookmarkList() const;
107 };
108 
109 struct SongStyle
110 {
111 	SongType type;
112 	std::vector<TrackAttribute> trackAttribs;	// Always sorted by number
113 };
114 
115 struct Bookmark
116 {
117 	std::string name = u8"";
118 	int order, step;
119 
120 	Bookmark(std::string argname, int argorder, int argstep);
121 };
122