1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#import "chrome/browser/ui/cocoa/applescript/bookmark_folder_applescript.h"
6
7#import "base/memory/scoped_nsobject.h"
8#import "base/string16.h"
9#include "base/sys_string_conversions.h"
10#include "chrome/browser/bookmarks/bookmark_model.h"
11#import "chrome/browser/ui/cocoa/applescript/bookmark_item_applescript.h"
12#import "chrome/browser/ui/cocoa/applescript/constants_applescript.h"
13#include "chrome/browser/ui/cocoa/applescript/error_applescript.h"
14#include "googleurl/src/gurl.h"
15
16@implementation BookmarkFolderAppleScript
17
18- (NSArray*)bookmarkFolders {
19  NSMutableArray* bookmarkFolders = [NSMutableArray
20      arrayWithCapacity:bookmarkNode_->child_count()];
21
22  for (int i = 0; i < bookmarkNode_->child_count(); ++i) {
23    const BookmarkNode* node = bookmarkNode_->GetChild(i);
24
25    if (!node->is_folder())
26      continue;
27    scoped_nsobject<BookmarkFolderAppleScript> bookmarkFolder(
28        [[BookmarkFolderAppleScript alloc]
29            initWithBookmarkNode:node]);
30    [bookmarkFolder setContainer:self
31                        property:AppleScript::kBookmarkFoldersProperty];
32    [bookmarkFolders addObject:bookmarkFolder];
33  }
34
35  return bookmarkFolders;
36}
37
38- (void)insertInBookmarkFolders:(id)aBookmarkFolder {
39  // This method gets called when a new bookmark folder is created so
40  // the container and property are set here.
41  [aBookmarkFolder setContainer:self
42                       property:AppleScript::kBookmarkFoldersProperty];
43  BookmarkModel* model = [self bookmarkModel];
44  if (!model)
45    return;
46
47  const BookmarkNode* node = model->AddFolder(bookmarkNode_,
48                                              bookmarkNode_->child_count(),
49                                              string16());
50  if (!node) {
51    AppleScript::SetError(AppleScript::errCreateBookmarkFolder);
52    return;
53  }
54
55  [aBookmarkFolder setBookmarkNode:node];
56}
57
58- (void)insertInBookmarkFolders:(id)aBookmarkFolder atIndex:(int)index {
59  // This method gets called when a new bookmark folder is created so
60  // the container and property are set here.
61  [aBookmarkFolder setContainer:self
62                       property:AppleScript::kBookmarkFoldersProperty];
63  int position = [self calculatePositionOfBookmarkFolderAt:index];
64
65  BookmarkModel* model = [self bookmarkModel];
66  if (!model)
67    return;
68
69  const BookmarkNode* node = model->AddFolder(bookmarkNode_,
70                                              position,
71                                              string16());
72  if (!node) {
73    AppleScript::SetError(AppleScript::errCreateBookmarkFolder);
74    return;
75  }
76
77  [aBookmarkFolder setBookmarkNode:node];
78}
79
80- (void)removeFromBookmarkFoldersAtIndex:(int)index {
81  int position = [self calculatePositionOfBookmarkFolderAt:index];
82
83  BookmarkModel* model = [self bookmarkModel];
84  if (!model)
85    return;
86
87  model->Remove(bookmarkNode_, position);
88}
89
90- (NSArray*)bookmarkItems {
91  NSMutableArray* bookmarkItems = [NSMutableArray
92      arrayWithCapacity:bookmarkNode_->child_count()];
93
94  for (int i = 0; i < bookmarkNode_->child_count(); ++i) {
95    const BookmarkNode* node = bookmarkNode_->GetChild(i);
96
97    if (!node->is_url())
98      continue;
99    scoped_nsobject<BookmarkFolderAppleScript> bookmarkItem(
100        [[BookmarkItemAppleScript alloc]
101            initWithBookmarkNode:node]);
102    [bookmarkItem setContainer:self
103                      property:AppleScript::kBookmarkItemsProperty];
104    [bookmarkItems addObject:bookmarkItem];
105  }
106
107  return bookmarkItems;
108}
109
110- (void)insertInBookmarkItems:(BookmarkItemAppleScript*)aBookmarkItem {
111  // This method gets called when a new bookmark item is created so
112  // the container and property are set here.
113  [aBookmarkItem setContainer:self
114                     property:AppleScript::kBookmarkItemsProperty];
115
116  BookmarkModel* model = [self bookmarkModel];
117  if (!model)
118    return;
119
120  GURL url = GURL(base::SysNSStringToUTF8([aBookmarkItem URL]));
121  if (!url.is_valid()) {
122    AppleScript::SetError(AppleScript::errInvalidURL);
123    return;
124  }
125
126  const BookmarkNode* node = model->AddURL(bookmarkNode_,
127                                           bookmarkNode_->child_count(),
128                                           string16(),
129                                           url);
130  if (!node) {
131    AppleScript::SetError(AppleScript::errCreateBookmarkItem);
132    return;
133  }
134
135  [aBookmarkItem setBookmarkNode:node];
136}
137
138- (void)insertInBookmarkItems:(BookmarkItemAppleScript*)aBookmarkItem
139                      atIndex:(int)index {
140  // This method gets called when a new bookmark item is created so
141  // the container and property are set here.
142  [aBookmarkItem setContainer:self
143                     property:AppleScript::kBookmarkItemsProperty];
144  int position = [self calculatePositionOfBookmarkItemAt:index];
145
146  BookmarkModel* model = [self bookmarkModel];
147  if (!model)
148    return;
149
150  GURL url(base::SysNSStringToUTF8([aBookmarkItem URL]));
151  if (!url.is_valid()) {
152    AppleScript::SetError(AppleScript::errInvalidURL);
153    return;
154  }
155
156  const BookmarkNode* node = model->AddURL(bookmarkNode_,
157                                           position,
158                                           string16(),
159                                           url);
160  if (!node) {
161    AppleScript::SetError(AppleScript::errCreateBookmarkItem);
162    return;
163  }
164
165  [aBookmarkItem setBookmarkNode:node];
166}
167
168- (void)removeFromBookmarkItemsAtIndex:(int)index {
169  int position = [self calculatePositionOfBookmarkItemAt:index];
170
171  BookmarkModel* model = [self bookmarkModel];
172  if (!model)
173    return;
174
175  model->Remove(bookmarkNode_, position);
176}
177
178- (int)calculatePositionOfBookmarkFolderAt:(int)index {
179  // Traverse through all the child nodes till the required node is found and
180  // return its position.
181  // AppleScript is 1-based therefore index is incremented by 1.
182  ++index;
183  int count = -1;
184  while (index) {
185    if (bookmarkNode_->GetChild(++count)->is_folder())
186      --index;
187  }
188  return count;
189}
190
191- (int)calculatePositionOfBookmarkItemAt:(int)index {
192  // Traverse through all the child nodes till the required node is found and
193  // return its position.
194  // AppleScript is 1-based therefore index is incremented by 1.
195  ++index;
196  int count = -1;
197  while (index) {
198    if (bookmarkNode_->GetChild(++count)->is_url())
199      --index;
200  }
201  return count;
202}
203
204@end
205